Agent 是不是更聪明的 ChatGPT:一次请求背后的循环机制

Agent 不是更聪明的 ChatGPT:一次请求背后的循环机制

你让 ChatGPT 把项目里的 moment 换成 dayjs,它通常会回你一整段修改建议。

你让 Claude Code、Codex 这类编码 Agent 做同一件事,它会自己打开 package.json,先看 dayjs 装没装;再搜出所有引用点,一个文件一个文件地改;最后跑一遍测试,确认没炸。

表面看,只是"多调了几个工具"。但两者的分野不在工具数量,而在谁握着那个循环

Chatbot 是你说一句、它回一句。Copilot 是你在干活、它给建议,接不接由你定。Agent 则把"想一步、做一步、看一步"的循环整个拿到了自己手里------人只负责给目标,Agent 负责一轮一轮推进,直到做完、失败,或被喊停。

本文就顺着一次真实请求,把这个循环拆开给你看。

一、ReAct 不难,难在每一轮都要收得住

Agent 的基础模式通常被概括成 ReAct:Reasoning、Acting、Observation。推理、行动、观察,然后进入下一轮。

简化成代码大概是这样:

ts 复制代码
while (!shouldStop) {
  const context = prepareContext();
  const response = await callModel(context);

  if (!response.toolCalls.length) {
    stop("模型认为任务已经完成");
  }

  const results = await executeTools(response.toolCalls);
  state.add(response, results);
}

真正投入生产的 Agent,循环里面塞的东西远不止这几行。

第一,准备工作不是把历史消息原样带上。它要检查上下文有没有接近上限,决定是否清理旧的工具结果、裁剪消息或者生成摘要。上下文处理得太晚,下一轮 API 可能直接拒绝请求。

第二,不是等模型把整段回答生成完才看工具调用。模型在流式输出时,工具名和参数会逐步出现:

json 复制代码
{"file_
path": "
src/uti
ls.ts"}

这里存在一个时机问题。解析太早,可能调用错误的工具,甚至因为 JSON 不完整直接崩溃;解析太晚,用户会盯着界面等,并发和反馈都跟不上。工程实现通常要一边接收 token,一边判断工具调用块是否已经完整,参数通过校验后再执行。

第三,执行工具时不能简单串行,也不能全部并发。读文件、Glob、Grep 这类只读操作可以并行;Edit 这类写操作必须串行;Bash 更麻烦,同为命令,lsrm 的风险完全不同,需要单独判断。

第四,工具结果回到上下文之后,这一轮才算结束,然后再准备下一轮。Agent 不是在执行一条超长指令,而是在反复完成"组装上下文、调用模型、执行工具、更新状态"。

二、流式输出为什么常用 SSE,而不是 WebSocket

LLM 的输出天然适合流式传输。模型本来就是一个 token 一个 token 地生成,等到完整回答生成完再返回,用户只会看到长时间白屏。

这里的通信方向和普通聊天不完全一样。虽然用户在界面上可以随时按停止、补充消息或者审批工具,但在一次生成过程中,主要数据流是服务端持续向客户端推送 token。WebSocket 提供全双工能力,当然能做;SSE 更贴近这种单向推送场景。

SSE 本质上是基于 HTTP 的长连接,协议本身带重连机制。客户端发一个请求,服务端持续通过事件流返回数据。

不过,SSE 是单向的,不代表用户不能批准工具执行。

一个常见的交互过程是:

  1. 模型流式输出,明确要调用某个需要授权的工具;
  2. 这一轮流结束,界面弹出审批;
  3. 用户点击允许,客户端发送一个普通的 HTTP 请求;
  4. 服务端执行工具,再开启一条新的 SSE 流,把后续结果推给客户端。

也就是说,审批走的是另一条请求,不需要硬塞进当前 SSE 连接里。

SSE 还有一个容易被忽略的问题:TCP 的半开状态。用户从 Wi-Fi 切到移动网络时,底层连接可能已经不可用,但浏览器还在等数据。HTTP 长连接不会自动知道对端已经失联。

解决办法通常有两层:

  • 服务端定期发送 SSE 注释作为心跳,保持连接可感知;
  • 客户端维护看门狗,记录最后一次收到数据的时间,超过阈值就主动断开并重连。

只做服务端心跳不够,客户端也得能发现"很久没消息了"。

三、工具可以边说边调用,但执行顺序要有确定性

模型在输出工具调用 JSON 时,有些实现会允许工具提前进入执行队列。这里最容易踩的坑是:把"可以并行"理解成"结果可以乱序返回"。

读文件和搜索可以同时跑,但写文件必须等前置读取和判断完成。Claude Code 一类实现的并发策略通常遵循一个朴素原则:只读操作能并发,写入操作串行,Shell 命令按具体动作判断。ls 可以并发,rm 最好单独串行处理。

即使多个只读工具并行执行,结果回填到上下文时通常也会按工具调用顺序排列。原因不复杂:

  • 下一轮模型看到的结果稳定;
  • 用户看到的过程可读;
  • 出现问题时方便对照调用和结果;
  • 测试更容易复现,不会因为返回顺序不同得到不同结果。

并发解决的是等待时间,顺序解决的是可控性。这两件事不能混在一起。

四、状态追踪决定 Agent 什么时候停

一个没有状态管理的 Agent,最典型的表现就是该停时不停,不该重试时继续重试。

循环至少要回答下面几个问题:

  • 现在跑到第几轮了?
  • 上一轮为什么继续?是正常推理,还是错误恢复、压缩重试?
  • 上下文压缩执行到哪里?压缩后释放了多少空间?
  • 输出被截断了几次?
  • 有没有挂起任务或者等待用户确认的操作?

这些问题看似琐碎,却决定了整个系统能不能刹车。

以 Claude Code 这类编码 Agent 的退出条件为例,常见停止原因不只一种:

  1. 模型没有返回工具调用;
  2. 流式连接被中断;
  3. 工具执行被中断;
  4. Hook 阻止继续执行;
  5. 达到最大轮数;
  6. 上下文过长,API 拒绝请求;
  7. 压缩之后上下文仍然过长,无法恢复。

这里有个很重要的设计思路:"模型说完成了"只是退出条件之一,不是唯一条件。

如果只相信模型自己的判断,那么连接异常、工具阻塞、上下文溢出、Hook 拒绝都会变成未知状态。一个可靠的循环需要同时理解模型状态、协议状态、工具状态和用户状态。

五、实时反馈不是 UI 装饰

Agent 跑一轮可能需要几十秒。如果界面只在全部完成后一次性给结果,用户不知道它是在读文件、执行命令,还是已经卡死。

更合理的方式是持续把中间状态展示出来:当前调用了什么工具、参数是什么、工具返回了什么、为什么进入下一轮。实现上通常会使用生成器或者事件流,把模型输出和工具事件不断推给上层。

这不仅是为了"看起来在动"。当 Agent 做错了,用户越早看到中间过程,越容易中断并纠正。等它改了二十个文件再发现方向错了,回滚成本会高得多。

反馈也不能把模型内部所有推理都原样暴露。应该展示可验证的动作:调用了什么工具、访问了哪个文件、执行结果如何,以及当前进入了哪个恢复分支。用户看到的是运行证据,不是装饰性的进度条。

六、Agent Loop 的真正复杂度在 Harness

模型负责推理和决定下一步,Harness 负责让这件事在真实环境里安全地发生。

它要处理上下文压缩、SSE 重连、工具并发、权限审批、错误恢复、状态记录、退出条件,以及用户按下 Ctrl+C 之后怎么收尾。模型换一个,这些工程问题仍然存在;Harness 写得太薄,换个更强的模型也救不回来。

回到开头那个"替换 moment 为 dayjs"的例子。用户只看到一句话,背后可能发生了十几轮循环:读配置、装依赖、全局搜索、修改文件、跑测试、根据报错回退、再次修改。

这就是 Agent 和 Chatbot 的分界。前者不是回答得更长,而是能够在环境里持续行动,并且知道什么时候应该停下来。

如果要验证一个 Agent 的 Loop 做得好不好,不要只看它能不能完成一次演示。更值得看的是:它遇到连接中断、工具报错、上下文溢出和用户拒绝时,还能不能把事情讲清楚,然后干净地退出。

相关推荐
武子康2 小时前
小智发出 abort 后,旧声音为什么还可能继续?
人工智能·llm·agent
七夜zippoe3 小时前
LLM 选型指南:Agent 场景下大模型的核心能力评估框架
ai·大模型·llm·agent·核心 能力
邵奈一3 小时前
05 从记账本到档案卡:Agent 记忆的存与管
人工智能·大模型·agent
XLYcmy3 小时前
ReasoningBank: Scaling Agent Self-Evolving with Reasoning Memory论文阅读
论文阅读·google·llm·agent·记忆·harness·自进化
降临-max3 小时前
从零开始快速开发一个 AI 辅助测试设计智能体(附完整源码)
软件测试·人工智能·大模型·agent·ai测试智能体
武子康3 小时前
SGLang 和 vLLM,拿自己的请求测一轮再选
人工智能·llm·agent
Sherotree4 小时前
Agent 工程笔记③:为什么要有评测集(比单次演示重要)
ai·agent·评测·系列
会飞的胖达喵6 小时前
MiniMax-Music3 本地全量模型部署与 API 生成实战
大模型·agent·音乐模型·minimax-music3
亦暖筑序6 小时前
AgentScope Java 实战:@Tool 方法里到底该不该写业务逻辑?
java·agent·ai编程