Agent SDK
一次调用与持续输入
选择 Prompt、Query 或 Session,理解输入关闭、结果边界和资源归属。
先选择调用方式
| 入口 | 适合的任务 | 谁关闭会话 |
|---|---|---|
client.Prompt | 后台摘要、只需要最终结果 | 函数内部关闭一次性流 |
client.Query | 一次任务,但要展示过程 | 调用者关闭返回的 Stream |
client.NewSession | 对话、审批界面、多个连续回合 | 调用者关闭 Session |
Session.StreamInput | 宿主持续提供用户消息 | 调用者管理输入通道并关闭 Session |
这些入口共用底层执行核心。选择 Prompt 不会关闭运行时的工具能力,它只是替你消费消息直到首个 result。若要限制工具,应配置权限与工具集合。
一次性流的使用顺序
先调用 Query,成功后安排 Close,再选择 Recv 或 Result 消费输出。读取到结果后即可结束本次任务,不需要等待所有内部后台事件。
stream, err := client.Query(ctx, client.QueryRequest{
Prompt: "阅读 README.md,说明如何启动项目。",
Options: options,
})
if err != nil {
return err
}
defer stream.Close(context.Background())
result, err := stream.Result(ctx)
if err != nil {
return err
}
if result.IsError {
return fmt.Errorf("任务失败:%s", result.Subtype)
}
fmt.Println(result.Result)
本页片段放在已有的 Go 函数中使用,ctx 和 options 来自快速开始。服务端清理时应为 Close 使用独立的短超时,避免沿用已经取消的请求 context。
持续输入不是并发会话
QueryRequest.Messages 和 Session.StreamInput 接受 <-chan protocol.OutboundMessage。通道提供一条持续输入来源;启用 Messages 时,不要同时依赖 Prompt 字段作为额外首条消息。
messages := make(chan protocol.OutboundMessage, 1)
messages <- protocol.NewUserTextMessage("阅读 README.md,提取启动步骤。")
close(messages)
stream, err := client.Query(ctx, client.QueryRequest{
Messages: messages,
Options: options,
})
if err != nil {
return err
}
defer stream.Close(context.Background())
宿主应确定谁拥有通道、谁关闭通道、取消时如何停止生产消息。不要由多个发送者各自调用 close。输入通道结束与任务成功是两件事,仍要消费最终结果。
一个输出流只保留一个消费者
Stream.Recv、Stream.Result 和 Session.Recv 都读取同一条底层消息通道。它们不是各自独立的订阅。如果一个 goroutine 展示文本,另一个 goroutine 同时等待 Result,两者会争抢消息。
应让一个读取循环拥有消息流,在循环内部把文本转发到界面,把终态交给任务管理器。使用 Recv 已读走 result 后,不要再调用 Result 等待同一结果。完整循环见消息流。
结束与取消
一次性 Query 返回的 Stream 拥有会话,Stream.Close 负责释放它。Session.Send 返回的 Stream 不拥有 Session;关闭它不能代替 Session.Close。停止当前回合应调用 Session.Interrupt,停止整个连接才调用 Close。
为长任务设置截止时间,并在停止后确认终态或连接关闭。不要把 HTTP 客户端断开直接解释成“运行时已停止”,详见取消与错误。