跳转至

生命周期钩子

每个扩展点都是 agent.Options 上的一个函数字段(无状态引擎则是 LoopConfig)。每个的 零值都是“无钩子”,所以裸 agent 就是一个朴素的工具循环。这些钩子让你拦截工具调用、在回合 之间切换模型、提前停止,并在每次请求前重塑上下文。

钩子的触发顺序

在一个回合内,钩子按如下顺序触发:

TransformContext        (就在构建请求之前)
  → assistant 轮次流式生成
  对每个工具调用:
    BeforeToolCall       (参数校验之后、执行之前)
      → Execute
    AfterToolCall        (执行之后、结果发出之前)
PrepareNextTurn          (该回合及其工具结果追加之后)
ShouldStopAfterTurn      (下一次请求开始之前)

拦截工具调用

BeforeToolCall 在参数校验之后、工具执行之前运行。返回 block = true 跳过该工具; reason 会成为模型看到的错误结果文本。

BeforeToolCall: func(c agent.BeforeToolCallCtx) (block bool, reason string) {
    if c.ToolCall.Name == "delete_file" {
        return true, "file deletion is disabled in this session"
    }
    return false, ""
},

AfterToolCall 在工具完成后运行。非 nil 的返回会逐字段覆盖结果;nil 字段保留执行得到的 值。

AfterToolCall: func(c agent.AfterToolCallCtx) *agent.AfterToolCallResult {
    if c.IsError {
        stop := true
        return &agent.AfterToolCallResult{Terminate: &stop} // 任一工具出错就结束运行
    }
    return nil
},

AfterToolCallResult 可覆盖 ContentDetailsIsErrorTerminate。给一批里 每个结果都设上 Terminate,该批之后即停止运行。两个钩子都按源序运行、绝不并发,即使 工具本身并行运行也是如此——见工具

回合间的模型切换

PrepareNextTurn 在每个回合后运行,可为下一回合替换模型、思考强度或上下文。由于历史按 请求重新适配,新模型甚至可以讲不同的 wire 协议。

PrepareNextTurn: func(c agent.TurnCtx) *agent.TurnUpdate {
    // 先用快模型起草,再用更强的模型评审(不同协议)。
    if len(c.NewMessages) == 2 {
        review := llm.GetModel("minimax-cn", "MiniMax-M3")
        return &agent.TurnUpdate{Model: &review}
    }
    return nil
},

TurnUpdate 携带可选的 ContextModelThinkingLevel;nil 字段保留当前值。 TurnCtx 把该回合的 assistant 消息、它的工具结果、当前上下文,以及 NewMessages—— 即运行此刻停止会返回的内容——交给钩子。

提前停止

ShouldStopAfterTurn 在下一次请求开始之前请求一次优雅停止。agent 没有内置的回合上限, 所以这里就是你防止失控循环的地方。

ShouldStopAfterTurn: func(c agent.TurnCtx) bool {
    return len(c.NewMessages) > 20 // 限制一次运行可追加的消息数
},

重塑上下文

TransformContext 在每次请求把 transcript 投影成 llm 消息之前调整它。它是上下文压缩 的挂载点——总结或丢弃旧回合以适配窗口——本包对此不提供默认实现。

TransformContext: func(messages []agent.AgentMessage) []agent.AgentMessage {
    if len(messages) <= 40 {
        return messages
    }
    return compact(messages) // 你的总结策略
},

它按请求运行,且不修改存储的 transcript,所以压缩只影响模型看到的内容,不影响 agent 的 记忆。

安全性

任何钩子的 panic 都会被恢复成一个终止错误事件,所以行为异常的回调会干净地结束运行,而不是 让进程崩溃。ConvertToLLM 同理(见消息与自定义类型)。