📑 本页目录(点开跳转)
17 · 实战项目
⏱ 三个项目,每个 1–3 天 | ⭐ 不做项目 = 没学过
🔗 可运行实践: 贯通 RAG、MCP、审批与评测的共同项目 。
🎯 一句话
三个递进的项目:单 Agent → 带验证循环 → 多 Agent。做完你就有了完整的手感。
💰 成本提示:项目一用第 1 章的
MockModel可以零成本开发调试,逻辑通了再换真模型。 项目二三建议用中档模型,全部做完大概几美元。
🧠 ADHD 专属:怎么保证做得完
项目是最容易半途而废的东西。三条规则:
- 先跑通最烂的版本。 别一开始就想做完美。烂版本能跑 = 已经赢了 80%
- 每个项目切成 ≤1 小时的任务(下面已经切好),完成一个打勾
- 不允许优化「还没跑通的东西」。跑通 → 打勾 → 才准优化
🚫 必须避免:花两天配环境。用最简单的方式跑起来,工程化以后再说。
🥉 项目一:终端研究助手(1 天)
目标:一个能「搜资料 → 读内容 → 给出带引用的回答」的命令行 Agent。
练什么:第 1 章的循环 + 第 7 章的工具设计。
任务清单
参考用时 · 45 分钟
搭骨架:复用第 1 章的run_agent循环,先用 MockModel 跑通参考用时 · 60 分钟
实现两个工具:search_web(query)—— 可用duckduckgo-search库或维基百科 APIread_page(url)—— requests + 粗提取正文,截断到 3000 字并注明已截断
参考用时 · 45 分钟
系统提示词:要求回答必须带来源 URL;资料不足要明说,不许编参考用时 · 45 分钟
测试 5 个问题:2 个简单事实、2 个需要多跳搜索、1 个资料里根本没有答案的参考用时 · 30 分钟
打磨工具返回:搜索结果只给标题+摘要+URL(第 7 章:别把整页塞给模型)参考用时 · 30 分钟
加护栏:max_steps+ token 计数器,每次任务结束打印成本
🔨 关键代码片段
def search_web(query: str, max_results: str = "5") -> str:
"""搜索网页。返回标题、摘要和链接,不返回正文。
需要正文时用 read_page(url)。"""
results = do_search(query, int(max_results))
if not results:
return f"没有找到关于「{query}」的结果。试试更宽泛的关键词。"
return "\n".join(
f"[{i}] {r.title}\n {r.snippet[:150]}\n {r.url}"
for i, r in enumerate(results)) # ⭐ 用短索引不用 UUID(第7章)
def read_page(url: str) -> str:
"""读取网页正文。内容会被截断。"""
text = extract_main_text(url)
LIMIT = 3000
if len(text) > LIMIT:
return (text[:LIMIT] +
f"\n\n[正文已截断,原文共 {len(text)} 字。"
f"如需后续内容,说明你要找什么,我会重新提取相关段落]")
return text
✅ 通关标准
- 多跳问题能自主「搜→读→再搜」至少两轮
- 找不到答案时明说,而不是编造 ⭐ 这条最容易翻车
- 每个结论都有来源 URL
🎁 加分
- 遇到搜索结果互相矛盾时,让 Agent 指出矛盾而非硬选一个
- 加一个
response_format参数(第 7 章),对比 token 消耗
🥈 项目二:带验证循环的代码修复 Agent(2 天)
目标:给它一个带失败测试的 Python 小项目,它自主「跑测试 → 读报错 → 改代码 → 再跑」直到全绿。
练什么:第 5、12 章的验证循环 —— 这是 Agent 编码能力的核心机制。
任务清单
参考用时 · 45 分钟
准备靶场:写一个 100 行左右的小模块(如日期处理工具)+ 10 个 pytest 用例,故意埋 3 个 bug 让 4 个用例失败参考用时 · 60 分钟
工具三件套:read_file(path)edit_file(path, old, new)—— 精确字符串替换,old 不唯一时报可行动的错误run_tests()—— subprocess 跑 pytest,返回精简后的失败摘要,不是全量输出
参考用时 · 45 分钟
循环策略写进系统提示词:每次只改一处 → 立即跑测试 → 读结果决定下一步;修好之前不许宣布完成参考用时 · 60 分钟
跑通全流程,观察它的轨迹:它先看了什么?误改过吗?怎么发现的?参考用时 · 60 分钟
加验证分离(第 12 章):完成后由一个全新上下文的「审查 Agent」检查 diff——它不知道修复过程,只看结果和测试,试图推翻结论参考用时 · 45 分钟
⭐ 故意给一个测试本身就错的靶场,看 Agent 会不会盲目迎合错误测试
🔨 关键:run_tests 的返回设计
def run_tests() -> str:
"""运行测试套件,返回失败摘要。"""
r = subprocess.run(["pytest", "-q", "--tb=short"],
capture_output=True, text=True, timeout=120)
if r.returncode == 0:
return "✅ 全部测试通过。"
# ⭐ 只返回失败部分,不返回全量输出(第4章:控制上下文)
fails = extract_failures(r.stdout) # 解析出失败的测试名 + 简短 traceback
return (f"❌ {len(fails)} 个测试失败:\n\n" +
"\n\n".join(f"{f.name}\n {f.short_trace}" for f in fails[:5]) +
(f"\n\n[还有 {len(fails)-5} 个失败未显示]" if len(fails) > 5 else ""))
✅ 通关标准
- 4 个失败用例全部修复,且没有改坏原本通过的
- Agent 至少完成 3 轮「改→测→读」循环,全程无人工干预
- 审查 Agent 至少抓出过一次问题(没抓出就自己埋个陷阱验证它在干活)
- T6 的发现写进笔记——这是你对「测试质量就是基础设施」的第一手体感
🥇 项目三:多 Agent 文档流水线(2–3 天)
目标:编排器-工作者架构——输入一个主题,产出一份多来源、经过审查的研究报告。
练什么:第 13 章的多 Agent 协作 + 第 4 章的上下文隔离。
架构
任务清单
参考用时 · 60 分钟
编排器提示词:产出结构化子任务(第 13 章)参考用时 · 60 分钟
工作者:复用项目一的研究 Agent,包一层「只返回 500 字摘要 + 来源列表」参考用时 · 45 分钟
并行跑工作者(concurrent.futures就行),聚合前先定聚合策略(第 6 章的忠告)参考用时 · 60 分钟
审查者 rubric(第 12 章:把「好不好」变成可回答的问题)参考用时 · 45 分钟
退回机制:审查不过 → 意见给编排器 → 只重跑有问题的部分(不从头来)参考用时 · 60 分钟
全流程跑 3 个主题,记录:总 token、耗时、审查退回了几次、每次退回抓的是什么参考用时 · 45 分钟
⭐ 等预算对照实验(第 13 章):把多 Agent 花掉的总 token 全给单 Agent,让它多轮迭代,比较质量
🔨 关键:结构化委派
subtasks = [
{"goal": "找出 2026 年 Q2 三家主要竞品的定价变化",
"output_format": "每家一段,含具体价格和变化时间,300字以内",
"tools": ["search_web", "read_page"],
"boundaries": "只看官方定价页,不要看第三方评测;不要分析原因(别人在做)"},
...
]
🔨 关键:审查 rubric
REVIEW_RUBRIC = """按四个维度审查报告,每项 0-25 分:
- 引用完整:每个事实结论都有来源吗?
- 引用有效:来源真的支持该结论吗?(抽查 3 条)
- 覆盖完整:子问题都被回答了吗?
- 内部一致:有互相矛盾的说法吗?
输出 JSON:{"引用完整":分,"引用有效":分,"覆盖":分,"一致":分,
"必须修复":["..."], "通过":true/false}
低于 70 分不通过。"""
✅ 通关标准
- 编排器的委派是结构化的,工作者之间没有重复劳动
- 审查者至少成功退回过一次,且第二轮真的变好了
- T7 的对照实验有结论——亲手验证「15 倍成本」值不值
📝 项目 README 模板(作品集用)
# 项目名
## 它做什么(一句话 + 一张架构图)
## 关键设计决策
- 为什么这里用工作流不用自主 Agent(附降级测试数据)
- 工具返回为什么这么设计(附 token 对比)
- 验证为什么分离(附审查者抓出的真实案例)
## 成本与表现
| 任务 | 轮数 | token | 成本 | 结果 |
## 踩过的坑 ← ⭐ 这一节最加分
1. ...
🔑 「踩过的坑」最加分——它证明你真的做过,而不是抄的教程。
🔗 这一章连到哪里
| 去哪 | 为什么 |
|---|---|
| Kaggle 25 | ⭐「先跑通最烂的版本,再逐环替换」—— 这套做法的方法论出处 |
| 上线之后 20 | 项目跑通之后的下一半:上线、监控、发现它悄悄变差 |
| 全景导论 16 | 做完这几个项目,用它来决定下一个方向挖哪里 |
✅ 检查点
- 三条通用规则是什么?为什么「先跑通最烂版本」排第一?
- 研究助手项目里,「找不到就明说,不许编」为什么必须写进提示词?
- 工具返回内容为什么要截断?不截断会怎样?
- 代码修复 Agent 的
run_tests为什么只返回失败摘要,而不是完整输出? - 为什么审查 Agent 必须用独立上下文?
- T6「故意给一个错的测试」这个实验在测什么?
- 项目三的 T7 等预算对照实验回答了什么问题?为什么这个问题重要?
👀 答案
- ①先跑通最烂版本 ②任务切成 ≤1 小时的块 ③没跑通不准优化。第一条排第一是因为一条能从输入跑到输出的完整链路,会立刻告诉你瓶颈在哪——而半成品连"哪一环最弱"都看不出来。
- 因为模型的默认倾向是"给出一个答案"而不是"承认不知道"。不显式授权它说"找不到",它就会编一个看起来合理的。这是幻觉最常见的来源之一。
- 因为工具返回的内容会全部进入上下文。一个返回 5 万字网页正文的工具,两次调用就把预算吃光了。不截断的直接后果是上下文腐烂,Agent 在第 5 轮就开始忘记任务目标。
- 同理——完整测试输出里绝大部分是"通过"的噪声。只返回失败摘要,既省上下文,又让模型的注意力集中在真正要修的地方。
- 因为共享上下文的审查会被"生成过程"污染——它看过那些推理,会倾向于认同。独立上下文的审查者只看产出物,判断更接近真实的第三方视角。🔗 这是第 12 章「生成与评估分离」的落地。
- 测模型会不会盲目迎合。给一个明显错误的测试,正确的行为是指出测试本身有问题,而不是改代码去迁就它。这直接对应第 12 章说的谄媚倾向。
- 回答「多 Agent 那 15 倍的 token 消耗,换来的效果提升值不值」。重要是因为多 Agent 的成本是隐性的——不做对照实验,你只会看到"效果好像更好了",而看不到代价。很多任务用单 Agent + 好工具就够了。
🛑 完成了?
三个高难度挑战在等你,每个都对准一个「普通项目练不到」的核心矛盾:
- ⚙️ 挑战A · 手搓 mini Agent 框架 —— 不用任何 SDK,从零造带上下文压缩和子 Agent 的框架
- 📏 挑战B · 评测驱动开发 —— 先建评测再写 Agent,戒掉玄学
- 🛡️ 挑战C · 提示注入攻防 —— 攻破自己的 Agent,再分层防住
⚡ 走神救援
先记住这几件事
- 先跑通最小版本,再改进;研究助手、代码修复和协作流水线分别验收。
- 研究助手保留可核对的证据;找不到就明说,工具输出要控制长度。
- 代码修复按修改、测试、读取失败结果循环;也要检查测试本身是否合理。
- 协作流水线使用明确的交付格式与审查标准,并在相同预算下和单 Agent 对照。