夜雨聆风学习资料网

ARTICLE · 1244615

AI Agent 总是“黑盒”?我们给它做了一台能回放的观测台

AI Agent 总是“黑盒”?我们给它做了一台能回放的观测台

AGENT LOOP / OBSERVER · 2026.10

AI Agent 总是“黑盒”?

我们给它做了一台能回放的观测台

从一句话到一次行动,拆解 Agent Loop 的产品、原理与工程实现:看得见、管得住、记得下、放得了。读完带走一套 Agent 排查框架。

一句话先说结论:模型负责“想”,循环负责“跑腿”;观测台负责让这一切看得见、管得住、记得下、放得了。

你可能也遇到过这些时刻:

·Agent 说“我已经改好了”,你却不知道它到底改了哪个文件;

·它卡了 40 秒,你分不清是在等模型、等工具,还是陷入了死循环;

·任务失败了,日志几万行,你只能从头翻;

·同一句话重复跑,结果不一样,却很难复现。

这不一定是因为模型不够聪明,而是因为 Agent 的“过程”没有被产品化。

我最近把这套过程做成了一台可以安装、可以操作、可以回放的观测台:Agent Loop Observer。它不是一个更大的日志面板,而是把 Agent 的内部循环拆开,让你能像看行车记录仪一样,看它怎么想、怎么做、在哪里停下。

FIG.01 / 入门页:五个角色与全景图 · 点开可放大先看“谁在做什么”,再看一条消息如何穿过整个系统。

读完这篇文章,你会带走三样东西:

01一个不用读源码也能懂的 Agent 心智模型:五个角色、九个瞬间。

02一个判断 Agent 是否“可观测”的四问框架。

03一套可以复用的排查顺序:先看阶段,再看事件,最后看账本。

01 / PLAIN WORDS

先讲人话:Agent Loop 到底是什么

模型本身只会两件事:想,以及说它想做什么。

它不能直接读你的文件、跑命令、查网页。真正把这些“想法”接到真实世界里的,是一个循环:

收下你的话 → 问模型 → 执行模型要的工具 → 把结果写回账本 → 再问模型 → 直到它说“可以了”。

这个循环,就是 Agent Loop。

你可以把它想成五个角色:

你点菜的人。

模型只会动嘴的顾问。

Agent Loop调度员兼跑腿。

工具顾问伸手能够到的东西。

账本只追加、不改写的流水账。

模型说“我要读这个文件”,循环去读;模型说“我要跑测试”,循环去跑;模型说“我说完了”,循环把这一轮收尾。模型负责决策,循环负责可靠性。一句话不是直接变成答案的,而是变成了一串有顺序的事件。看懂这串事件,你才真正看懂了 Agent。

02 / FROM DEMO TO PRODUCT

为什么“能跑”不等于“可用”

很多 Agent Demo 都能跑通一次。但一旦放进真实工作,问题会立刻出现:它为什么停在这里?它刚才到底调用了什么?这个结果是模型编的,还是工具返回的?如果重跑一次,我能不能复现?

我把这些追问压缩成四个问题。四个里只要有一个答不上来,它就还停留在 Demo 阶段。它们也是我判断一个 Agent 系统是否“可观测”的四问框架:

01看得见

现在走到哪一步?输入、Turn、Step、模型、工具,还是收尾?

02管得住

能不能取消、保留队列、插话、注入上下文?

03记得下

每一步有没有 durable 记录(崩溃后还在),而不是只打在控制台?

04放得了

能不能按时间回放,并从同一份记录重建状态?

日志能回答一部分,但日志不是产品。真正的产品要能操作、能验证、能复盘。

03 / SIX TABS

产品全景:六个页签,一台工作台

Agent Loop Observer 以插件形式安装在 Harness 里,侧边栏点开就是六个页签:

入门三分钟大图、九阶段动画、22 条小白词典、6 条常见疑问。

实时当前阶段、Agent 卡片、事件时间轴、Loop 状态、控制面板。

记录把一次运行写成自包含的 JSONL,可导出。

重放逐帧回放,重建 Turn/Step、inbox、消息、请求和工具状态。

图解九张可交互动图,从全景到工具调度、取消、持久化、对外通信。

接口39 条模块间契约,回答“这条线走的是什么接口、什么时序”。

FIG.02 / 实时页:阶段条、事件时间轴与 Loop 状态 · 点开可放大顶部九阶段条告诉你“现在在哪”,中间时间轴告诉你“刚刚发生了什么”,右侧告诉你“状态是什么”。

它更像一台工作台,而不是一块监控大屏。大屏告诉你“有多少”,工作台让你“能动手”。

04 / NINE MOMENTS

九个瞬间:一轮对话到底发生了什么

把一轮对话拆开,其实只有九个瞬间:

01输入:你的消息进入收件箱;

02Turn 开始:这一轮工作正式打开;

03Step 开始:准备一次模型调用;

04提示词准入:决定系统提示词是追加、替换还是清空;

05请求:把配置、历史消息、工具清单打包;

06模型流:token 一个个回来;

07工具:模型要求读文件、跑命令,循环执行并写回结果;

08下一 Step:还有结果要处理,就回到第 3 步;

09结束:没有更多工作,写入结束原因,驱动回到空闲。

FIG.03 / 一轮对话的九个瞬间 · 点开可放大Turn 是“把这件事做完”,Step 是其中一次“问模型 + 可能用工具”的小回合

这里最容易混淆的是 Turn 和 Step。

·Turn 像一次出差:从出发到回来,是一整段;

·Step 像出差中的一次办事:问一次模型,可能顺便跑一个工具。

一个 Turn 通常有很多 Step。因为模型每要一次工具,循环就要先把工具执行完、把结果写回账本,再问下一次。看懂这九步,80% 的 Agent 问题都能先定位到阶段,而不是一头扎进日志。

05 / WHY REPLAY WORKS

三个核心设计:为什么它能“回放”

1

Session log 是唯一事实源

Agent 的每一步都会写进一条只追加的 Session 日志:Turn 边界、Step 边界、请求头、提示词、模型消息、工具调用、工具结果。

·只追加,不改写;

·每条事件有单调递增的 seq;

·模型看到的一切,都必须能从这份日志重建。

这意味着:日志不是“辅助信息”,它就是事实本身。

2

重放不是“重新执行”,而是“重新折叠”

很多人以为重放就是把模型再跑一遍。不是。这台观测台的重放,做的是确定性的 fold:把记录里的 durable 事件,按与服务端相同的语义折叠;重建 inbox、Turn/Step 边界、可见消息、请求、工具配对、token;而且 不调用模型,不执行工具,不产生新的副作用。同一份记录,折叠出来的状态必须一致。这就是“可复现”的基础。

FIG.04 / 重放页:逐帧回放与重建状态 · 点开可放大左边是事件时间轴,右边是从记录里折叠出来的状态

3

Projection checkpoint:记录可不可信,不靠感觉

重放最怕“看起来对,其实漏了事件”。所以每个 turn/end 会记录一次投影快照:当时的 inbox 和 Turn 边界。重放时,fold 出来的状态会和快照逐字段比较:

·verified:记录可以被独立重建;

·mismatch:记录有缺口,或者 fold 语义漂移。

这把“我觉得没问题”变成了“检查过,0 个不匹配”。

06 / ENGINEERING DETAILS

四个反直觉的工程细节

这部分偏技术,但决定了系统是否可信。

细节一

通知不是状态

Agent 会发 agent/inbox/inserted、claimed、discarded 这些通知。它们很好用,但不是状态。真正的状态只有一个来源:agent/inbox/spliced。通知只告诉你“发生了什么”,状态要重放 splice 才能得到。如果把通知当状态,重放就会得到一份“看起来差不多”的假历史。

细节二

append 成功 ≠ 已经落盘

写入 Session 日志时,append 成功只代表“被接受了”;只有 flush 成功,才承诺崩溃后仍然存在。这解释了为什么有些系统“日志都写了”,重启后却少了一段。持久化有两个阶段,不能混为一谈。

细节三

工具可以并行完成,但必须按模型顺序提交

模型可能一次要四个工具。安全的可以并行,不安全的必须排队。但无论谁先完成,结果都必须按模型给出的顺序写回。否则下一轮历史会变得不可预测,模型会“看不懂自己刚才做了什么”。

细节四

取消也要收尾

取消不是把一切抹掉:

·已经给用户看到的文本,要保留为 interrupted 消息;

·没派发的工具,要补上合成错误结果;

·turn/end 必须正常写入,并带上取消原因。

一个系统怎么处理取消,比它怎么处理成功更能说明工程质量。

07 / CONTRACTS & TIMING

接口与时序:把黑盒拆成 39 条契约

光有“事件流”还不够。真实排障时,你经常需要回答:

·这条线是方法调用,还是事件?

·这个事件是 emit(通知)、serial(顺序等待)、waterfall(层层包装)还是 parallel(并行等待)?

·它是同步的,还是 fire-and-forget?

·它发生在 step/start 之前还是之后?

·它保证顺序,还是只保证最终一致?

所以这台观测台把模块之间的连接也产品化了:39 条契约(接口约定),每条都标注机制、精确接口、方向、同步方式、时序、负载和“最容易踩的坑”。

FIG.05 / 对外通信全景 · 点开可放大进程内方法调用、进程内事件、跨进程/网络,是三种完全不同的通信层级

先看系统的对外边界:浏览器、模型服务、工具世界、持久化、子 Agent、审批和遥测,各自通过什么方式说话。再看契约本身:

再看契约本身:机制、精确接口、方向、同步方式、时序、负载和坑,一条一张卡。

FIG.06 / 接口页:每条契约一张卡 · 点开可放大按分组和机制过滤,搜索模块、事件名或 API

例如:

·浏览器发消息:sessionController.prompt({ mode }) → Agent.followup / steer;

·准备模型请求:prepareCall → PreparedLlmCall;

·工具执行前:tools/pre-execute 可以 allow / deny / ask,没有审批能力时 ask 会直接变成 deny;

·日志提交:session.append 是同步的,但 session/event 是 post-commit 的通知;

·持久化:SessionHandle.append 是尽力而为,flush 才是崩溃屏障。

图上的每条连线也有编号:短边放不下完整 API,就把编号和完整接口放在图上方的图例里;点击编号或图例,打开完整契约。

TIME

时间:不是“一个总耗时”

排障时,大家最容易问“为什么这么慢”。但这台系统会把时间拆成九段:

01排队 / 唤醒;

02组装 / 提示词准入;

03准备请求;

04首 token + 生成;

05工具执行;

06下一步;

07持久化;

08投影 / UI;

09时钟基准。

FIG.07 / 时间都花在哪 · 点开可放大每段都给出起止事件,并提醒哪些包含排队/重试、哪些不能直接相加

这比“总共 38 秒”有用得多。你可以明确看到:是模型首 token 慢,还是工具在排队,还是 UI 推送的批量延迟。

08 / A REAL INCIDENT

一次真实排障:从“它卡住了”到“逐个排除假设”

在一次真实运行里,有一轮对话跑了 13 个 Step、120 次工具调用,记录文件 2.3 MB。表面看,它“卡在工具阶段”。

但打开实时页,阶段条停在“工具”;再看时间轴,你可以把“卡住”拆成几个可验证的问题:

·request/header 显示这一轮带了 35 个工具;

·tool/call 和 tool/result 是否成对?如果成对,说明工具本身在正常返回;

·是否有一个较早的调用还没提交,导致后面的结果在等它?这正是模型顺序提交的典型表现;

·turn/end 的 reason 是什么?它告诉你最终是完成、取消还是报错。

如果没有观测台,你只能猜“是不是模型又抽风了”。有了阶段、事件和账本,你可以逐个排除假设,而不是在几万行日志里碰运气。

这就是可观测性的价值:不是让你看到更多日志,而是让你更快排除错误假设。

09 / WHO IT IS FOR

谁适合用,能得到什么

FOR BEGINNERS

如果你是刚接触 Agent 的人

·先用“入门”建立心智模型:五个角色、九个瞬间;

·再看“图解”的九张动图,把抽象概念变成可点击的节点;

·最后用 22 条词典和 6 条 FAQ 补概念。

FOR BUILDERS

如果你是 Agent 开发者

·用实时页定位是提示词、请求、模型流还是工具;

·用重放页复现一次失败,而不是靠截图和记忆;

·用接口页查清“这个事件到底什么时候发、能不能拦截”。

FOR PLATFORMS

如果你是平台 / 基础设施团队

·用记录做审计、成本分析和事后复盘;

·用 projection 校验判断记录是否完整;

·用公开的 Agent API 做管理,不绕过产品边界。

FOR TEAMS

如果你是团队负责人

·把一次事故的记录交给新人,让他自己回放;

·把“第几步、哪个工具、什么结果”变成团队共同语言;

·用同一份证据讨论,而不是各自猜。

它也有边界:它不是模型评测集,不是路由器,也不是日志收集器。provider 的线上字节、MCP 的协议帧、子 Agent 的内部 Cordis 树,目前都不在它的采集范围内。它专注的是 Agent Loop 的过程层。

10 / GET STARTED

五分钟上手,以及四条可复用的原则

安装只需要在工作区安装这个插件包(bundle),然后在侧边栏点开 Agent Loop:

plugin_manager install_bundle  target: <你的工作区>/agent-loop-observer

建议的第一次使用顺序:

01入门:先看三分钟大图和九阶段动画;

02实时:选一个 Agent,看阶段条、时间轴和 Loop 状态;

03记录:点“开始记录”,操作一会儿,再“停止记录”;

04重放:载入记录,拖动/播放,看右侧重建状态和一致性校验;

05接口:需要抠细节时,再查 39 条契约。

最后,我想留下四条比这个插件更重要的原则。它们适用于任何 Agent 系统:

原则一:单一事实源。模型看到的一切,都必须能从一份日志重建。

原则二:确定性重放。重放的是事实和状态,不是再跑一次模型。

原则三:可验证。记录是否完整,要用 projection 检查点证明,而不是靠感觉。

原则四:只读观测 + 显式控制。观测不改变系统;管理动作走公开 API,并留下记录。

如果一个 Agent 系统做不到这四条,它的能力越强,风险越大。

11 / CLOSING

写在最后

Agent 行业现在很像早期的 Web:每个人都在讨论“模型能做什么”,但真正决定它能不能进入生产环境的,往往是那些不性感的部分——可观测、可回放、可审计、可控制。

这台观测台是我对“Agent 过程层”的一次完整回答:把黑盒拆成阶段,把阶段拆成事件,把事件写成账本,再把账本变成可以回放的界面。它目前是 DSH/Harness 上的一个本地 bundle,仍在快速迭代。

如果你也在做 Agent、平台工程或可观测性,欢迎关注我。接下来我会继续拆:

·provider 的线上字节到底长什么样;

·MCP 的协议帧怎么观测;

·子 Agent 的调用树如何还原;

·以及更多真实排障复盘。

也欢迎在评论区告诉我:你最想观测 Agent 的哪一步?

如果这篇文章对你有帮助,点个在看,让更多做 Agent 的人看到。我们下期见。

附录

8 个术语,带走就能用

Agent能自己循环工作的助手实例。

Turn把一件事做完的一整段。

Step一次模型调用,加上它请求的工具。

Inbox待处理输入,分“下一轮”和“下一步”。

Tool call模型请求一个真实动作。

Session log只追加的事实账本。

Projection把账本折叠成可读状态。

KV Cache模型对相同前缀的缓存,前缀不变就能复用。

本文约 4500 字,7 张图。图中数据来自真实运行界面,部分会话标识已隐去。

相关学习资料