00b 全景:一个循环推出整个系列
每篇单独看都能懂,合起来却串不成一张图,原因是系列按专题切开,每篇自成一体,没讲清楚”为什么学完这篇就会冒出下一篇的问题”。
这一篇只做一件事:给出一条主线,让 16 篇都能挂上去。 不讲新知识。
读法:先读完这篇,之后每读一篇,回来看它挂在哪一层、拧的是哪个旋钮。
一、主干:一句话
Agent 就是一个循环:把上下文发给模型 → 模型要么直接回答,要么要求调用工具 → 程序执行工具,把结果塞回上下文 → 再来一轮,直到模型不再调用工具,或者程序叫停。
flowchart LR
CTX[上下文<br/>系统提示词 + 历史 + 工具结果] --> M[模型]
M -->|直接回答| END[结束]
M -->|要调工具| T[执行工具]
T -->|结果塞回去| CTX
STOP[程序叫停<br/>步数上限 / 卡住 / 预算用完] -.-> END
后面 16 篇讲的都是这个循环本身,或者它跑起来以后遇到的问题。
二、问题链:循环跑起来之后,一个个冒出来的问题
把循环真跑起来,问题是按顺序冒出来的。按冒出来的先后分成四层,再加一层输出:
flowchart TB
L1["<b>第一层 让循环转起来</b><br/>01 模型 → 02 调用 → 03 提示词 → 04 工具 → 05 循环"]
L2["<b>第二层 让循环转得久、转得稳</b><br/>06 上下文 · 07 状态恢复 · 08 RAG"]
L3["<b>第三层 确认它转得对、不闯祸</b><br/>09 评测 · 10 可观测 · 11 安全"]
L4["<b>第四层 把循环放进真实系统</b><br/>12 框架与协议 · 13 多 Agent · 14 后端"]
L5["<b>输出</b><br/>15 系统设计题 · 16 项目怎么讲"]
L1 --> L2 --> L3 --> L4 --> L5
每一篇对应的问题,一句话说清:
| 层 | 冒出来的问题 | 篇 | 核心回答 |
|---|---|---|---|
| 一、让循环转起来 | 模型到底是什么 | 01 | 输入 token、输出 token,按 token 收费,每次按概率挑下一个词,所以会瞎编 |
| 调模型会超时、限流、断流 | 02 | 超时、重试、降级、流式输出 | |
| 怎么让它按要求输出 | 03 | 系统提示词结构、示例、结构化输出、按 bad case 迭代 | |
| 模型只会说话,怎么让它做事 | 04 | 模型只提出”我要调哪个工具、传什么参数”,程序校验后执行,再把结果回填 | |
| 这一轮一轮怎么组织、什么时候停 | 05 | 流程能写死就用工作流,写不死才交给模型;停止条件和预算必须有 | |
| 二、让循环转得久、转得稳 | 转了几十轮,上下文塞满、变贵、变笨 | 06 | 截断、压缩、外置记忆、缓存前缀 |
| 转到一半进程挂了 | 07 | 检查点、幂等、人工审批后续跑 | |
| 模型不知道你的私有知识 | 08 | 先检索、再把材料放进上下文,本质是给上下文找料 | |
| 三、确认它转得对、不闯祸 | 改了提示词或换了模型,到底变好没有 | 09 | 固定测试集、多跑几次看方差、留出集、回归关卡 |
| 线上某次失败了,是哪一轮哪一步 | 10 | 每次模型调用、工具调用都记一条,能按一次任务串起来看 | |
| 能执行命令就能删文件,能读网页就能被注入 | 11 | 权限最小、沙箱、白名单、危险操作要人确认 | |
| 四、把循环放进真实系统 | 循环不想自己写,工具接口想通用 | 12 | 框架替你写循环和状态;MCP 是工具的通用插座 |
| 一个循环的上下文装不下、串行太慢 | 13 | 拆成多个循环,代价是成本翻倍、信息在交接时丢失 | |
| 用户要通过网页用它 | 14 / 14b | 接口、流式推送、异步、任务队列、限流鉴权 | |
| 输出 | 面试现场让你设计一个 | 15 | 用上面四层当检查清单,一层层过 |
| 面试让你讲项目 | 16 | 同样按四层讲:做了什么、没做什么、数据是多少 |
记住左边四层的名字和各层的问题,右边的篇目自然能对上。忘了某篇讲什么时,先想”循环跑到哪一步会出这个问题”。
三、四个旋钮:每篇都在做同样的取舍
问题链是纵向的主线。还有一条横向的线:几乎每个”该怎么选”,都是在下面四个旋钮之间取舍。
| 旋钮 | 意思 |
|---|---|
| 质量 | 任务做成的比例、答案对不对 |
| 成本 | 花多少 token、多少钱 |
| 延迟 | 用户等多久 |
| 可控 | 行为能不能预测、出错能不能查、会不会闯祸 |
各篇里的典型取舍:
| 篇 | 选择 | 拿什么换什么 |
|---|---|---|
| 01 | 选大模型还是小模型 | 成本、延迟 换 质量 |
| 05 | 工作流还是 Agent | 可控 换 应对开放任务的能力 |
| 06 | 压缩历史 | 丢一些细节(质量)换 成本 |
| 07 | 每步存检查点 | 一点延迟和存储 换 挂了能续跑 |
| 08 | 检索后再加重排 | 延迟 换 质量。项目里每条查询从 33ms 变成 1126ms,R@1 仍是 45/48,没换来 |
| 09 | 每种配置跑 3 轮 | 成本 换 结论可信 |
| 11 | 命令白名单 | 灵活 换 可控 |
| 13 | 拆成多 Agent | 成本 换 并行和更干净的上下文 |
面试官问”为什么这么做""为什么不用 X”,回答基本都能落到这四个旋钮上:我在这里更看重哪个,放弃了哪个,有没有数据支撑。
四、一次请求从头走到尾
拿 CrossBuild Agent 的一次真实请求走一遍:“把 libpng 交叉编译到 aarch64”。每一步标出对应篇目。
sequenceDiagram
participant U as 浏览器
participant S as 后端 server/app.py
participant L as 循环 build_agent.py
participant M as 模型 DeepSeek
participant T as 工具 tools.py
U->>S: GET /api/build(14)
S->>L: 加锁,同一时间只跑一个构建(14)
loop 最多 40 步(05)
L->>M: 系统提示词 + 历史 + 工具结果(03、06)
M-->>L: tool_calls:run_command(02、04)
L->>T: 白名单 + 路径检查(11)
T-->>L: 执行结果,过长就截断(06)
L->>L: 记一条调用记录到 runs.db(10)
L-->>U: SSE 推一条事件(14)
Note over L,M: 构建失败时模型调 search_knowledge 查经验库(08)
end
L->>L: 卡住或到上限 → 验收:扫产物是不是 aarch64(05)
L-->>U: 推送最终结果
同一条路径,用文字再过一遍:
- 浏览器请求
/api/build,后端用StreamingResponse推 SSE,并用一把锁保证同时只跑一个构建 —— 14 - 进入循环,
MAX_STEPS默认 40 —— 05 - 每轮把系统提示词、历史消息、上一轮工具结果拼成 messages —— 03、06
- 用 OpenAI 兼容的 SDK 调 DeepSeek,SDK 自带重试 —— 01、02
- 模型返回
tool_calls,比如要执行cmake ..—— 04 run_command先查命令在不在白名单,再查参数有没有指到工作目录外 —— 11- 执行命令,输出太长就截断并把全文存到文件 —— 06
- 构建失败时,系统提示词要求先调
search_knowledge查经验库 —— 08 - 每次工具调用都写进
runs.db—— 10 - 同样的调用反复出现就判定卡住,到步数上限也停;停下后不信模型说的”成功了”,自己跑一遍构建、扫产物架构 —— 05
- LangGraph 版本(
graph_agent.py)把同样的循环画成图,每个节点结束存检查点,kill 掉能续跑 —— 07、12 - 事后评测:另选 5 个 Agent 没见过的项目当留出集,不开知识库、BM25、混合检索三种配置各跑 3 轮,结果都是 15/15,加知识库没有带来可测量的收益 —— 09
这个项目没有用多 Agent(13),被问到时可以直说:单个循环的上下文够用,拆开只会多花钱。
五、自测
合上文章,拿白纸做下面三件事。卡住的地方,就是还没接上的地方,回到对应篇补。
1. 写出主干那句话,画出循环图。
检查要点
四个元素缺一不可:上下文、模型、工具执行、结果回填。再加两个出口:模型不再调工具;程序叫停(步数、卡住、预算)。
2. 默写四层问题链,每层至少说出两个问题和对应篇号。
检查要点
转起来(01–05)、转得久转得稳(06–08)、转得对不闯祸(09–11)、放进真实系统(12–14)。顺序比篇号重要:说得出”为什么这个问题在这一层才冒出来”才算真记住。
3. 从浏览器发请求开始,把第四节那条路径讲一遍,每一步说出属于哪篇、拧的是哪个旋钮。
检查要点
能讲到”验收不信模型自己说的成功”和”知识库查了但评测没测出收益”这两处,说明主线和项目都接上了。
下一篇:01 大模型基础——循环里最核心的零件:模型本身。