Agent SDK

一次调用与持续输入

选择 Prompt、Query 或 Session,理解输入关闭、结果边界和资源归属。

先选择调用方式

入口适合的任务谁关闭会话
client.Prompt后台摘要、只需要最终结果函数内部关闭一次性流
client.Query一次任务,但要展示过程调用者关闭返回的 Stream
client.NewSession对话、审批界面、多个连续回合调用者关闭 Session
Session.StreamInput宿主持续提供用户消息调用者管理输入通道并关闭 Session

这些入口共用底层执行核心。选择 Prompt 不会关闭运行时的工具能力,它只是替你消费消息直到首个 result。若要限制工具,应配置权限与工具集合。

一次性流的使用顺序

先调用 Query,成功后安排 Close,再选择 RecvResult 消费输出。读取到结果后即可结束本次任务,不需要等待所有内部后台事件。

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 函数中使用,ctxoptions 来自快速开始。服务端清理时应为 Close 使用独立的短超时,避免沿用已经取消的请求 context。

持续输入不是并发会话

QueryRequest.MessagesSession.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.RecvStream.ResultSession.Recv 都读取同一条底层消息通道。它们不是各自独立的订阅。如果一个 goroutine 展示文本,另一个 goroutine 同时等待 Result,两者会争抢消息。

应让一个读取循环拥有消息流,在循环内部把文本转发到界面,把终态交给任务管理器。使用 Recv 已读走 result 后,不要再调用 Result 等待同一结果。完整循环见消息流

结束与取消

一次性 Query 返回的 Stream 拥有会话,Stream.Close 负责释放它。Session.Send 返回的 Stream 不拥有 Session;关闭它不能代替 Session.Close。停止当前回合应调用 Session.Interrupt,停止整个连接才调用 Close。

为长任务设置截止时间,并在停止后确认终态或连接关闭。不要把 HTTP 客户端断开直接解释成“运行时已停止”,详见取消与错误