2
0
0

Agent 循环与对话流程

2026-08-14
2026-09-07
Agent 循环与对话流程
文章摘要
|

入门04:Agent 循环与对话流程

这篇文章讲的是:当用户发了一条消息,系统内部是怎么"跑"的——就像前端框架的 render 流程,但更复杂,因为 AI 可能要"思考-行动"好几轮才能给出最终回复。


1. 什么是 Turn/Step 循环?

先看一个真实场景

你问 AI:帮我去搜索 Node.js 最新版本,然后写一个 hello world 文件。

AI 会这样做:

  1. 先搜网页(调用搜索工具)
  2. 看到搜索结果后,再写文件(调用文件写入工具)
  3. 最后告诉你搞定了

所以用户发一条消息,AI 可能要做多轮操作。这就是 Turn/Step 循环:

用户发消息
Turn 开始
Step 1: AI 思考
需要调用工具?
执行工具
生成回复
Turn 结束
  • Turn(回合) = 一次完整的"用户提问 → AI 最终回复"
  • Step(步骤) = Turn 里的一轮"AI 思考 → 可能调用工具"
  • 一个 Turn 可以有多个 Step(如果 AI 连续调工具)

就像 React 的 render 流程:一次 setState 可能触发多次 render(因为 useEffect 里又 setState),直到状态稳定。


2. 完整流程(从发消息到收到回复)

2.1 第一步:收到消息

聊天记录本Agent引擎API网关用户聊天记录本Agent引擎API网关用户"帮我搜 Node.js 最新版本"转给引擎处理记录"用户说了一句话"记录"回合开始"

2.2 第二步:拼装提示词

提示词组装器聊天记录本Agent引擎提示词组装器聊天记录本Agent引擎收集系统指令收集当前时间、目录等上下文收集所有工具定义替换模板变量 {{xxx}}"把历史记录给我"返回处理过的消息列表"帮我组装完整的提示词"拼好的完整提示词

拼好的提示词包含:

  • 系统提示:来自各插件的 instructions(就像 HTML 的 <head>
  • 上下文:当前时间、工作目录等(就像模板引擎的 locals)
  • 工具定义:所有可用的工具清单(就像 API 文档)
  • 消息历史:从事件日志"算"出来的对话记录

2.3 第三步:调用 AI

Session模型适配器LLM运行时Agent引擎Session模型适配器LLM运行时Agent引擎就像 axios 的 adapter把统一请求转成具体 API 格式"调用 AI 模型""翻译成模型的 API 格式"流式返回(SSE)返回 AI 的回复记录"AI 回了一句话"记录"步骤开始"

2.4 第四步:执行工具(如果需要)

Session具体工具工具运行时Agent引擎Session具体工具工具运行时Agent引擎"AI 要调用 web_search"执行前拦截(waterfall)守卫检查(超时?权限?)执行搜索返回搜索结果执行后拦截(waterfall)工具执行结果记录"工具执行结果"

2.5 第五步:循环直到完成

用户Session工具运行时AI模型Agent引擎用户Session工具运行时AI模型Agent引擎第1轮第2轮(把搜索结果发给 AI)第3轮调用 AI"我要搜索"执行搜索搜索完成记录步骤结束"这是搜索结果,继续""我要写文件"写文件写入成功记录步骤结束"文件写好了,继续""搞定了,生成回复"记录回合结束"已搜索到 Node.js v22.0.0,已创建 hello.js"

3. 关键代码(简化版)

// 简化自 packages/core/agent-loop/src/index.ts
// 核心逻辑总共就 30 多行
async function 处理用户消息(input: 用户输入) {
  // 1. 记录
  session.append('user/message', input)
  session.append('turn/start', {})

  // 2. 循环:AI 思考 → 执行工具 → 再思考 → 直到不再调用工具
  while (true) {
    // 3. 准备要发给 AI 的内容
    const messages = session.deriveMessages()  // 从历史记录算消息
    const prompt = await systemPrompt.assemble({ messages })
    const tools = toolRuntime.getDefinitions()  // 获取所有工具

    // 4. 调 AI
    const response = await llm.stream({
      messages: prompt.messages,
      tools: tools,
    })

    session.append('assistant/message', response)

    // 5. 如果 AI 没调用工具,说明回答完了,结束
    if (response.toolCalls.length === 0) {
      break
    }

    // 6. AI 要调用工具,执行它
    for (const call of response.toolCalls) {
      const execution = toolRuntime.createExecution(call.name, call.args)
      const result = await execution.execute()
      session.append('tool/result', { call, result })
    }
  }

  // 7. 结束回合
  session.append('turn/end', {})
  return response
}

4. 扩展点(在哪里可以"插一脚")

Agent 循环在多个关键点暴露了 Waterfall 事件,就像 Express 中间件:

事件啥时候触发能干啥
agent/pre-step每轮开始前修改输入、加额外信息
agent/post-step每轮结束后检查结果、触发特殊操作
llm/stream调 AI 时修改请求内容、拦截响应
tools/pre-execute执行工具前改参数、加守卫
tools/post-execute执行工具后改结果、记日志
system-prompt/assemble拼提示词时加自定义指令

5. 实际场景:搜索 + 写文件

文件工具搜索工具AI模型Agent用户文件工具搜索工具AI模型Agent用户"搜 Node.js 版本,写 hello world"发提示词决定调用 web_searchweb_search("Node.js latest version")搜索结果: v22.0.0把搜索结果发给 AI决定调用 writewrite("hello.js", "console.log('Hello World')")写入成功把写入结果发给 AI生成最终回复"已完成!Node.js v22.0.0,已创建 hello.js"

要点总结

  • Turn = 一次完整的问答(用户发→AI 最终回)
  • Step = Turn 里的一轮"AI 思考 + 可能调工具"
  • 一个 Turn 可能多个 Step:就像 React 的多次 render
  • 核心流程:记录消息 → 拼提示词 → 调 AI → 执行工具 → 循环
  • 消息历史从事件日志"算"出来,不是直接存的
  • 6 个 Waterfall 扩展点,可以"插一脚"

进阶阅读

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!