01
闭环:模型不做事,只有循环在做事
模型是一个纯函数:进去一段文本,出来一段文本。动作、副作用、停止条件,全都发生在循环里。
读图四个框构成闭环;朱红虚线框是框架的职责,不在模型里。
关键左侧 messages[] 每转一圈就变长——这就是第 4 张图要处理的成本来源。
判断如果任务能用 if/else 写完,就不要上 agent。你付出的是延迟、成本与不可复现。
02
采样:每一步只是一次「下一个 token」的分布
模型不执行算法,它在做条件采样。看懂这一层,就知道为什么结构化输出必须靠约束解码,而不是靠请求。
① 文本 → token(子词单元,不是字符也不是词)
② 每一步重算上下文 → 打分 → 采样一个 token
成本 ≈ O((prompt + n·out)²) · 每步都要重放整段历史
当前上下文
—
下一 token 的概率分布(top-5)
■ 采样到的不是「最合理」,是分布里抽中的那个
推论 1需要精确计算 → 调工具。别让模型数数、算钱、比日期。
推论 2要 JSON 就上 schema 约束解码;「请只输出 JSON」是祈祷,不是契约。
推论 3temperature=0 只是更确定,不等于可复现:浮点、批处理、模型版本都会变。
03
工具:模型唯一的「手」,每次调用都是一次边界
模型输出 name + args,运行时校验、执行、把结果作为新消息回填。工具报错写得好不好,直接决定 agent 能不能自愈。
运行时:校验 → 权限 → 执行
—
回填进上下文的消息
—
错误信息的两种写法
—
设计工具描述是写给模型的文档:参数自解释、枚举穷举、错误写成可恢复提示。
数量3~7 个高内聚工具 > 30 个细碎工具。工具越多,选错率越高。
安全每个工具都是权限边界。别给模型无限 shell、无配额写操作、静默删除接口。
04
上下文:agent 真正的状态机
记忆不在模型里,在你每步塞进去的消息数组里。窗口就是 agent 的全部世界,塞满时必须做取舍。
预算占用
0 / 200k tokens
等待开始…
四种取舍
滑动窗口 · 丢最旧 —— 便宜,会丢目标
摘要压缩 · 模型总结 —— 有信息损失
外部记忆 · 落盘再检索 —— 需要索引
结构化状态 · todo/JSON —— 最稳,要设计
摘要压缩 · 模型总结 —— 有信息损失
外部记忆 · 落盘再检索 —— 需要索引
结构化状态 · todo/JSON —— 最稳,要设计
第一坑工具输出原样回填:一次 install 或抓网页就是几万 token,95% 是噪声。
做法大结果写文件,上下文只留「路径 + 前 40 行 + 怎么按需读取」。
自检如果只留 5 条消息 agent 就干不下去,说明状态存在聊天记录里,而不是结构化状态里。
05
ReAct:让推理被真实观测约束
每轮先想、再做一个动作、拿到真实返回。没有 observation,模型只是在自我暗示。
trace
变体路径确定 → Plan-and-Execute 省 token;失败要记住教训 → Reflexion。
解析动作解析必须容错:解析失败本身要变成一条 observation 回喂,而不是抛异常崩循环。
取舍thought 要不要给用户看,是产品决策,不是技术决策。
06
验证:把「完成」的定义从模型手里拿走
模型很擅长生成「看起来对」的结果。可靠 agent = 外部验证器 + 原始错误回流。
round 0
外部验证器(不采信模型自述)
回流进上下文的原始错误
—
VERIFIED · 允许返回
顺序编译器 → 单测 → 真跑一遍看退出码 → schema 断言 → 第二个模型当 critic(最弱)。
原则能写成断言的,就不要写成 prompt。
critic 用法只问可核查的问题(哪条断言没过、哪一行),别问「你觉得好吗」。
07
编排:拆分的唯一理由是上下文隔离与并行
不是「像人类团队那样分工」。子任务的输入输出必须是结构化契约,不是自由聊天。
先问单 agent + 更好的工具 + 验证器能不能解决?能,就别拆。
代价N 个 agent ≈ N 倍 token 与延迟,再加通信开销与不一致风险。
拓扑Supervisor 最可控 → Pipeline 最可测 → Blackboard 适合长任务 → 自由对话群最难调试。
08
失效面:agent 很少「答错」,多数是结构性卡死
六种死法,每种都有可埋点的信号。把它们做成指标,比换更强的模型更有效。
必埋每轮 token/成本 · 工具成功率 · 同参重复调用次数 · 步数 P50/P99 · 终止原因分布。
兜底同参重复即打断;连续 3 轮无进展就升级或找人;每轮保留结构化状态。
前提没有这些指标,你无法判断一次改动是变好还是变坏。
09
边界:模型可以提议任何动作,能不能执行由运行时说了算
风险分级 → 自动 / 人工批准 / 拒绝 → 沙箱执行 → 审计日志。拒绝理由也要回喂,让模型改道而不是重试。
提议的动作队列
闸门状态
等待动作…
steps 0 / 12
tokens 0
cost $0.0000
wall 0.0s
tokens 0
cost $0.0000
wall 0.0s
■ 外部内容永远是数据,不是指令
沙箱三层:进程(无网络)· 文件(白名单)· 凭据(最小权限、可撤销)
头号威胁prompt injection:只要会读外部内容,内容里就可能有指令。
闸门写操作、生产环境、破坏性命令必须经人;拒绝信息作为 observation 回喂。
预算按任务设限,不按调用。到限不是崩,而是输出当前最佳结果 + 说明卡在哪。
10
骨架:把前面九张图写成 20 行
逐行高亮,右侧是这一行在运行时真正产生的效果。换任意模型 SDK,这个循环都成立。
运行中…
生产化还要补结构化输出约束 · 流式与中断 · 工具级超时重试 · 崩溃可恢复的持久化状态 · 全链路 trace。
为什么这么写每一步都在防前面某张图里的失效:去重防打转、截断防污染、验证防自述、上限防烧钱。
上不上 agent路径能用 if/else 写清楚 → 用工作流。Agent 只买「事先不知道下一步」这件事。
11
责任面:六层职责各自防什么
成熟度不看 prompt 写得多好,看状态在哪、边界在哪、失败怎么被看到、成本怎么被限住。
自检六层里哪一层你还没有?缺的通常不是模型,而是 verify 与 guard。
动手写一个只有 2 个工具 + 1 个验证器的 agent,任务限定「修一个失败的测试」。
分界线准备 10 个固定任务当回归集,每次改架构都跑一遍——这是玩具与系统的分界。