落地实践
收藏了 19 章知识点,不如亲手做完一个真实项目。这篇收官长文用「给博客加一个 AI 助手」做贯穿示例:怎么选题不烂尾、19 个知识点逐个落地并验收、能跑起来的 RAG 代码、上线清单和复盘节奏。
为什么收官章是「动手做」
学到这里,你脑子里应该已经装了不少概念:Loop、RAG、Eval、流式、护栏……但有个残酷的事实:没在自己的项目里踩过坑的知识,都不算你的。 看十篇讲 RAG 的文章,不如亲手被「检索回来的 chunk 根本答非所问」折磨一次。道理在纸上是自洽的,一落到真实数据、真实用户、真实成本上,到处都是从书里看不来的毛边。
所以这一章不讲新知识,只讲一件事:怎么把前面 19 章真正用起来。我会用一个贯穿示例——给这个博客站点加一个 AI 助手——展示每一步怎么做决策。这个助手能回答读者关于站内文章的问题、推荐文章、陪读者聊技术选型。麻雀虽小,五脏俱全:它有检索、有生成、有工具、有 eval、有上线和迭代,整条路线的每个知识点都能在里面找到位置。
第一步:选定一个真实项目
练手项目最大的陷阱是「假」:假数据、假用户、假需求,做完往 GitHub 一扔,再也不碰。这样的项目练不出工程直觉。选项目有三个硬判据:
- 小而完整:能在 2~4 周内做出端到端闭环(用户输入 → AI 处理 → 用户拿到结果)。「完整」比「大」重要,因为只有完整才会逼你面对部署、成本、脏数据这些真问题
- 有真实用户:哪怕用户只有你自己和三个朋友。真实用户会提真问题、制造真 badcase,这是任何合成数据都替代不了的
- 你自己在乎:你是它的重度用户,好不好用你有直觉判断,迭代有内在动力
「给博客加 AI 助手」刚好三条全中:博客是你自己的站点(在乎)、读者是真实用户、问答+推荐的闭环一周内能跑起来。类似的候选还有:给自己的笔记软件加语义搜索、给团队内部文档站加问答机器人、给自己常逛的社区做摘要 Agent。
先砍出一个 MVP 边界:第一版只做「基于站内文章的问答 + 文章推荐」,流式输出,不做多轮记忆、不做登录、不做生成式 UI。边界写在纸上,后续任何「顺便加个 XX」的念头都先记下来而不是立刻做。
反例:什么样的项目会烂尾
判据从正面说完了,再看四个典型的烂尾画像,每一个都对应违反了一条判据——
- 宏大叙事型:「我要做一个 AI 驱动的个人操作系统 / 全自动炒股 Agent」。三个月过去还在搭架构,闭环永远「下周就能跑通」。死因是违反「小而完整」——项目大到你在热情耗尽之前根本看不到端到端的那条细线,而没有闭环就没有任何可验证的东西
- 玩具数据型:拿 Kaggle 上清洗好的数据集做「智能客服」,demo 演示完美,接真实数据第一天就被打穿——真实用户不会按数据集分布提问。死因是违反「有真实用户」,假数据给你的是假信心
- 无人使用型:「给我自己的照片集做个 AI 相册」,做完发了个朋友圈集了二十个赞,然后没人再用,包括你自己。没有真实用户就没有反馈流,没有反馈流就没有迭代的理由,项目自然死亡
- 技术驱动型:「我想学 LangGraph / 多 Agent,所以找个项目套一下」。需求是后贴的,功能是围绕框架特性而不是用户问题设计的,学完了项目也就失去了存在意义。技术应该是手段,一旦它变成目的,项目就成了练习册,而不是作品
判断方法很简单:问自己「三个月后谁还在用它?」。如果答案里没有具体的人(哪怕只有你自己),换个选题。
第二步:把 19 个知识点逐个映射进项目
这是本章的核心。很多人学完一条路线的问题是「知识在天上,项目在地上」——下面这张映射表把它们钉在一起。左列是前面章节的知识点,中列是它在博客 AI 助手里具体落在哪,右列是验收标准——怎么算这个知识点真的落地了,而不是「我看过文档」:
| 章节知识点 | 在博客 AI 助手里的落点 | 验收标准 |
|---|---|---|
| LLM 基本原理 | 理解上下文窗口限制:一篇长文 + 对话历史塞不下,所以必须做检索而非全文灌入 | 能算出单次问答的 token 构成,说清为什么不能全文灌入 |
| 模型选型 | 问答主链路用便宜快的小模型(GPT-4o-mini / DeepSeek 级),只在用户反馈「答得差」时升级重试 | 有一张不同模型在 eval 集上的质量/成本/延迟对比记录 |
| Prompt Engineering | 系统提示词明确角色(「只基于提供的文章片段回答」),规定引用格式与拒答策略 | 诱导编造类 eval 样本全部通过,拒答时不胡编 |
| 上下文工程 | 每轮只携带最近 N 条消息 + 本轮检索结果,超长时摘要压缩历史 | 连续 10 轮对话不爆窗口、不丢主题,有压缩策略在生效 |
| Agent 核心概念 | 判断选型:问答是 Workflow(检索→生成,固定两步),「帮我规划阅读路径」才上 Agentic Loop | 能向人讲清哪条链路是 Workflow、哪条是 Loop,以及为什么 |
| 规划与推理策略 | 单轮问答几乎不需要任务分解;只在「帮我规划阅读路径」这类多步请求上,先让模型输出一份显式计划(读哪几篇、什么顺序、为什么),再逐条执行 | MVP 阶段论证了「为什么不需要」并写下触发条件:当请求平均需要 3 步以上工具调用时,才引入 plan-then-execute |
| 工具调用 | 两个原子工具:search_articles(query) 和 get_article(slug),粒度对齐「一次原子操作」 | 工具 schema 有描述和参数约束,模型在 20 条测试里选对工具 ≥ 90% |
| MCP | 把博客内容检索封装成 MCP Server,让 Claude Code 等外部 Agent 也能查你的博客 | 在 Claude Code 里真的连上并成功查到一篇文章 |
| 记忆与状态 | 会话级短期记忆存数据库;读者偏好(如「只看前端文章」)作为长期记忆写入 | 刷新页面会话可恢复;偏好能在后续回答中被引用 |
| RAG 实战 | 全文核心:markdown 按小节 chunking,向量 + 关键词混合检索,答案带引用链接 | 检索相关类 eval 样本的召回命中率 ≥ 80%,引用可点通 |
| 多 Agent 系统 | MVP 阶段不用——但预留接口,未来可拆出「检索 Agent」和「写作风格 Agent」 | 说得出「为什么现在不用」的理由,而不是没考虑过 |
| Computer Use | 明确不用:博客内容有 API 和文件系统可以直接读写,让模型截图点鼠标是拿最不可靠的接口干最可靠的事 | 能讲清 Computer Use 的适用边界(无 API 的遗留 GUI 软件),并证明博客场景不属于它 |
| 主流框架 | 用 Vercel AI SDK(和 Next.js 同生态),不裸写 SSE,也不上重型编排 | 流式与工具调用没有手写协议解析,代码里没有框架之外的胶水 |
| Agent 工程化 | 建一个 30 条的 eval 问题集;每次改 prompt 或 chunking 策略后跑一遍对比 | eval 跑分有历史记录,能回答「这次改动是变好了还是变差了」 |
| 什么是 AI Native | 助手不是「加了 AI 的搜索框」,而是读者表达意图(「我搞不懂 RAG」)直接得到答案和导读 | 新用户不看说明书就能用自然语言完成一次有效问答 |
| AI Native 交互 | 对话式 UI + 流式逐字输出 + 答案内嵌可点击的文章卡片(生成式 UI 的最小形态) | 首 token < 2s,回答中的文章以卡片呈现且可点击跳转 |
| LLM 应用架构 | Next.js Route Handler + SSE 流式;模型 API key 只在服务端 | 前端源码和网络面板里都搜不到 key,流式无代理层断裂 |
| 可靠性设计 | 检索为空时明确说「博客里没写过」;API 超时降级为非流式;输出做引用校验 | 三种故障注入测试(空检索/超时/断流)都有明确用户可见结果 |
| 案例拆解 | 抄 Cursor 的作业:上下文只给「相关的」,答案永远附来源,让用户可以验证 | 每条回答都有出处,且抽样 10 条人工核对无张冠李戴 |
注意表里的一个模式:每个知识点的落点都伴随着一次「做或不做」的判断。MVP 阶段多 Agent 不用上、记忆只做两层、模型只用一档——落地实践教你的不只是「怎么用」,更是「什么时候不用」。验收标准那一列同理:它的作用是防止「我以为我用了」,每一行都必须能被第三方验证。
争议:一步到位,还是小步快跑?
做这个项目时你会遇到第一个路线之争,值得把正反方都摆出来:
- 正方(一步到位):AI 应用的质量是系统性的——检索、prompt、模型互相耦合,先上糙版本会让早期用户形成「这东西不行」的印象,而第一印象不可逆。况且 eval 集、日志、护栏迟早要做,晚做不如早做,免得返工
- 反方(小步快跑):你对「什么叫行」的理解,只有在真实用户用过之后才是对的。闭门调三个月,很可能把 80% 的精力花在没人关心的维度上。早一天上线,就早一天开始积累真实的 badcase,而 badcase 才是质量改进的唯一可靠燃料
我的判断:链路一步到位,质量小步快跑。 端到端的细线(能问、能答、有引用)要一次搭通,不要分期——没有闭环的项目没有反馈;但链路上每一环的质量(检索准度、prompt 打磨、交互细节)必须靠上线后的真实数据迭代,不要试图在上线前调到完美。一句话:完整性提前,完美度延后。
进阶方向:造一个 Coding Agent
博客助手上线并稳定迭代一个月后,如果你想要更硬核的第二个项目,造一个能读你代码库、帮你改 bug 的 Coding Agent 是天然的下一站——它几乎复用你在博客助手里练过的每一块肌肉,但每一块都要求你练得更深。它同样满足选题三判据:用户是你自己,闭环就是「提需求 → 改代码 → 测试通过」,而你天天都在乎它好不好用。
有三个地方是博客助手没教过你的:
代码库索引。表面上是把 RAG 章的切块与检索搬过来,但切块单位变了:markdown 按「小节」切,代码要按「函数 / 类」切——按固定行数硬切会把一个函数拦腰截断,检索回来全是半成品。MVP 阶段可以取巧:按空行和函数签名行做启发式切分,够跑;等「召回的片段缺定义」这类 badcase 多起来,再上线 AST 感知的切块。检索还是老配方:关键词打底,同义问题多了再加 embedding。
diff 编辑策略。这是 Coding Agent 独有的核心决策——模型说「改这里」,你怎么落到文件上?两条主流路线,失败模式完全不同:
- search/replace 块:模型输出「找到这段原文、替换成这段新文」,工具做精确匹配后替换。省 token、改动可审计;但失败模式是匹配不上——模型凭记忆复述的代码和文件里的真实内容在缩进、空行、注释上差一点点,整个替换就失败,需要有「模糊匹配 + 失败重述」的兜底
- 整文件覆写:模型直接输出改完后的完整文件。永远不会匹配失败;但失败模式更阴——悄悄丢代码(长文件生成到一半开始偷懒省略)、token 成本随文件长度线性涨、diff 噪音大到无法 review
实践结论:小文件覆写、大文件 search/replace,并且每次落盘前先做语法校验(比如用对应语言的 parser 跑一遍),不通过就退回让模型重写——这是可靠性设计章节在 Coding 场景的具体形态。
测试反馈回路。这才是 Coding Agent 的引擎,也是它和聊天机器人的本质区别:代码世界自带裁判。跑测试 → 读报错 → 改 → 再跑,这个闭环的每一圈都有一个客观的通过/失败信号,不需要人盯着打分。正因为有这个信号,Agentic Loop 在 Coding 场景才真正成立——模型可以在没有人干预的情况下自己收敛。反过来,这也是你 eval 的天然素材:一组「带 failing test 的真实 issue」就是现成的评测集,测试通过就是验收标准。
最后是一张能力复用对照,帮你看清哪些是搬家、哪些是开荒:
| 能力 | 从博客助手迁移? |
|---|---|
| RAG(切块/检索/引用) | 直接迁移,切块单位从「小节」换成「函数」 |
| Prompt 工程(角色/拒答/格式约束) | 直接迁移,约束力要求更高——输出必须能被工具解析 |
| eval 与 badcase 复盘节奏 | 直接迁移,且评测信号更强(测试通过与否) |
| 流式 UI 与成本/预算控制 | 直接迁移,几乎不用改 |
| 工具设计 | 新挑战:工具数量从 2 个涨到十几个,粒度决定 Loop 步数 |
| 长 Loop 的上下文管理 | 新挑战:几十轮工具调用后上下文必然爆炸,要做压缩与隔离 |
| 执行安全 | 新挑战:Agent 能跑命令,沙箱和权限从「可选」变「必须」 |
做完这两个项目你会发现:知识点还是那 19 个,但每个的深度都被重新犁了一遍。这就是「做项目」和「看路线」的差别。
第三步:搭出最小闭环
核心链路就三步:检索相关文章片段 → 连同问题一起发给模型 → 流式返回答案并附引用。整个「RAG」不需要向量数据库,几十行关键词打分就够 MVP 用了——这是刻意的:先用最简单的实现把闭环跑通,把升级检索留给你上线后第一次迭代(那时候你手里有真实 badcase,知道该往哪个方向升级)。
先是检索模块,切块 + 打分,零外部依赖:
// lib/rag.ts —— 最小 RAG:按小节切块,关键词重叠度打分
import fs from "node:fs";
import path from "node:path";
export interface Chunk {
slug: string;
title: string;
text: string;
}
let cache: Chunk[] | null = null;
// 英文按词,中文按单字 + 二元组,粗糙但零依赖、可解释
function tokenize(s: string): string[] {
const words = s.toLowerCase().match(/[a-z0-9]+/g) ?? [];
const han = s.match(/[\u4e00-\u9fff]/g) ?? [];
const bigrams = han.slice(1).map((c, i) => han[i] + c);
return [...words, ...han, ...bigrams];
}
function loadChunks(): Chunk[] {
if (cache) return cache;
const dir = path.join(process.cwd(), "content/posts");
cache = fs.readdirSync(dir).flatMap((file) => {
const slug = file.replace(/\.md$/, "");
const md = fs.readFileSync(path.join(dir, file), "utf8");
const title = md.match(/^#\s+(.+)$/m)?.[1] ?? slug;
return md
.split(/^##\s+/m) // 按二级标题切块,保住语义边界
.filter((s) => s.trim().length > 50)
.map((text) => ({ slug, title, text: text.trim() }));
});
return cache;
}
export async function searchArticles(query: string, topK = 5): Promise<Chunk[]> {
const q = new Set(tokenize(query));
return loadChunks()
.map((c) => {
const tokens = tokenize(c.title + "\n" + c.text);
const hits = tokens.filter((t) => q.has(t)).length;
// 除以长度平方根做归一:长块不天然占便宜
return { ...c, score: hits / Math.sqrt(tokens.length) };
})
.filter((c) => c.score > 0)
.sort((a, b) => b.score - a.score)
.slice(0, topK);
}
然后是接口层:检索先行(这是 Workflow 不是 Agent——路径固定),流式输出,引用来源随响应头下发给前端渲染文章卡片,同时在 onFinish 里落日志,为复盘积累燃料:
// app/api/chat/route.ts
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
import { searchArticles } from "@/lib/rag";
export async function POST(req: Request) {
const { messages } = await req.json();
const question: string = messages[messages.length - 1].content;
const chunks = await searchArticles(question, 5);
const result = streamText({
model: openai("gpt-4o-mini"),
system: [
"你是本博客的 AI 助手。只根据下面编号的文章片段回答。",
"在用到某片段的句子末尾标注 [^序号],序号对应片段编号。",
"片段里没有答案,就直接说博客里没写过,不要编造。",
"",
...chunks.map((c, i) => `[${i + 1}] 《${c.title}》\n${c.text}`),
].join("\n\n"),
messages,
onFinish: ({ text }) => {
// 每次问答落日志:问题、命中片段、答案 —— 复盘迭代的燃料
console.log(JSON.stringify({
question,
hits: chunks.map((c) => c.slug),
answer: text,
}));
},
});
// 引用来源随响应头下发,前端据此把 [^n] 渲染成可点击的文章卡片
const sources = chunks.map((c) => ({ slug: c.slug, title: c.title }));
return result.toDataStreamResponse({
headers: { "x-sources": encodeURIComponent(JSON.stringify(sources)) },
});
}
前端一个输入框 + 一个消息列表,消费流式响应,读 x-sources 头渲染引用卡片,总共不到一百行。第一天的目标就是让这个闭环跑通,哪怕检索还是最糙的关键词匹配。闭环先通,再逐段优化——这比「先把 RAG 调到完美再接前端」的错误顺序快十倍,因为你永远先有东西可以给真人试。
什么时候该把关键词检索升级成向量检索或混合检索?不要凭感觉,等 badcase 说话:当你发现「检索未召回」类 badcase 里大量是同义不同词造成的(用户问「怎么省钱」,文章写的是「成本控制」),关键词匹配就到天花板了,这时候上 embedding 才有明确收益;而如果 badcase 主要是「片段缺上下文」,该改的是切块而不是检索器。让数据替你选升级方向,而不是让教程替你选。
第四步:从 Demo 到上线的检查清单
Demo 和上线之间隔着一条鸿沟,鸿沟里全是「非功能性」问题。这份清单每项都附了不做的后果——多数线上事故不是因为不知道要做,而是觉得「应该没事」:
功能正确性
- 准备 20~30 条 eval 问题集(覆盖:能答的、答不了的、诱导编造的、站外问题),每次改动后跑一遍 —— 不做:调优变玄学,你分不清是改好了还是运气好
- 答案里的引用链接都能点通、确实来自被引文章 —— 不做:引用成了新型幻觉,比不引用更伤信任
- 长对话(10 轮以上)不爆上下文、不丢主题 —— 不做:深度用户(最有价值的那批)恰好最先踩到
可靠性
- 检索为空 / 模型超时 / 流中断,三种异常都有明确的用户可见文案 —— 不做:用户面对白屏或转圈,默认结论是「这产品坏了」,而不是「网络抖动」
- 模型接口有重试与超时熔断,失败时降级为静态提示 —— 不做:上游一次抖动变成你的一次宕机
- 断开后重发不产生重复扣费或脏状态(幂等) —— 不做:月底账单里有一笔说不清的重复消耗
成本与性能
- 算过单笔问答成本(chunks token 数 × 单价),设每日预算告警 —— 不做:被刷接口时,你是看账单才知道的
- 首 token 延迟 < 2s(流式) —— 不做:用户在第 3 秒关掉页面,你的答案质量再好也没人看到
- 高频问题有缓存 —— 不做:同一个「这个博客用什么技术栈」每天付一百次模型费
安全
- API key 只在服务端,前端零暴露 —— 不做:key 被扒走后几小时内被打满,且账单算你的
- 提示词注入防御:用户输入与文章片段都被视为「数据」,不能覆盖系统指令 —— 不做:你的助手可以被诱导说出任何话,截图传播时署名是你的博客
- 有频率限制 —— 不做:你成了别人免费的 GPT 代理
上线后
- 每次问答落日志(问题、命中 chunks、用户反馈) —— 不做:没有数据,迭代全靠拍脑袋,上面所有优化的前提都不存在
- 有反馈入口(👍/👎),badcase 能一键归集 —— 不做:用户想帮你改进都找不到入口,只能默默流失
这份清单的价值不在「全做完」,而在每一项你都做过一次决策:做、不做、还是记下以后做。明知故犯叫权衡,不知而犯才叫事故。
第五步:复盘与迭代
上线不是终点,是迭代的起点。真正有效的迭代节奏是数据驱动的小循环:
- 每周看 badcase:把 👎 和日志里明显答歪的问答捞出来,按下表分类归因
- badcase 进 eval 集:每个确认的 badcase 都变成 eval 集的一条新样本
- 一次只改一个变量:改 chunking 就跑 eval,改 prompt 也跑 eval,但不要同时改——否则没法归因
- 每月回看映射表:哪些知识点真用上了?哪些判断(比如「不用多 Agent」)被验证或推翻了?写下来
badcase 分类是复盘里最见功力的部分。类别直接决定修法,分错类就会改错地方:
| 类别 | 典型症状 | 根因层 | 修法 |
|---|---|---|---|
| 检索未召回 | 答案说「没写过」,但其实写过 | 检索 | 改切块、加混合检索、上向量 |
| 召回但切烂 | 引用了对的片段,但片段缺上下文,答得片面 | 切块 | 调 chunk 边界与重叠 |
| 提示词失控 | 该拒答的瞎编、引用格式乱、口吻不对 | Prompt | 补系统指令 + 加对应 eval 样本 |
| 问题超范围 | 问的根本不是博客内容 | 产品 | 明确拒答 + 引导,不算质量事故 |
| 能力天花板 | 检索和 prompt 都对,模型就是答不好 | 模型 | 记录样本,换更强模型验证,别在 prompt 上死磕 |
eval 集的维护也要有节奏,否则它会腐烂:初始用你想到的高频问题写 20~30 条;每周把确认的 badcase 入库,eval 集应该单调增长,只增不删(过时样本标注停用而不是删除,留着防回归);每次改动跑全量对比,通过率下降必须说清原因才能合入;每月审查一次分布,哪类问题占比过高就补其他类,防止你只对某一类过拟合。冻结 v1 上线时的跑分作为基线,三个月后回看,那条曲线就是这个项目给你最真实的成绩单。
最后,复盘最容易被跳过的部分是写下来。不写的复盘只是感觉,写下来的复盘才能沉淀成下次选项目时的直觉。
常见误区
- 先做宏大架构再动手:上来就设计多 Agent、插件系统、多模型路由——MVP 阶段这些全是负债,先让闭环跑起来
- 用假数据自嗨:拿三条精心准备的 demo 问题测试当然全对,真实用户的第一句话就能把你打回原形,所以要尽早上线给真人用
- 跳过 eval 直接调:没有 eval 集的调优是玄学,你分不清是改好了还是运气好
- 功能蔓延:做着做着想加语音输入、图片理解、微信机器人……记住 MVP 边界,新想法先进 backlog
- 上线即遗忘:项目最大的价值在上线后的迭代过程,不在上线那一刻
术语表
| 名词 | 定义 | 一句话直觉 | 常见混淆 |
|---|---|---|---|
| MVP | 能完成端到端闭环的最小产品版本 | 砍到再砍就没有「完整体验」为止 | 不是「半成品」:功能少但闭环完整 |
| 闭环 | 用户输入到拿到结果的完整链路 | 一圈能转起来,哪怕转得糙 | 不是「流程图好看」:能跑才叫闭环 |
| badcase | 真实使用中产出错误/低质结果的案例 | 用户用脚投票投出来的错题 | 不是 bug:模型「正常发挥」但结果差也算 |
| eval 集 | 用于回归验证的质量评测样本集合 | 项目的错题本 + 模拟考卷 | 不是测试集:会随 badcase 持续增长 |
| 验收标准 | 判断某个能力是否真正落地的可验证条件 | 第三方能照着检查,不靠自我感觉 | 不是需求描述:需求说做什么,验收说怎么算做完 |
| 单变量调优 | 每次只改一个因素并对比效果 | 像对照实验,改一个量才知道是谁起的作用 | 不是效率低:同时改多个才是真的慢 |
| 基线 | 冻结的历史版本跑分,用于对比 | 成绩单上的第一条刻度线 | 不是目标:基线用来防退化,不是用来达标的 |
| 降级 | 核心依赖故障时切换到更弱但可用的方案 | 飞机引擎坏一个,滑翔也要落地 | 不是失败:用户无感知地拿到次优结果才是降级 |
| 幂等 | 同一操作执行多次与一次效果相同 | 重试的保险丝 | 不是重试本身:重试是行为,幂等是行为安全的前提 |
| 提示词注入 | 用户或外部内容试图覆盖系统指令的攻击 | 别人往你助手耳朵里塞小纸条 | 不只是「越狱」:被检索文档里的恶意内容也算 |
| 引用校验 | 验证答案引用的来源真实且相关 | 让每句话能拿出证据 | 不等于消除幻觉:校验的是出处,内容仍可能错 |
| 迭代 | 基于反馈的小步改进循环 | 改一点、量一次、再改 | 不是返工:返工是推翻重来,迭代是在闭环上生长 |
参考材料
- Patterns for Building LLM-based Systems & Products — Eugene Yan 的 LLM 产品落地模式总结,从评估到护栏一应俱全
- Your AI Product Needs Evals — Hamel Husain 关于「先建 eval 再迭代」的经典文章
- Building A Generative AI Platform — Chip Huyen 的 GenAI 平台架构长文,上线前要考虑的它都列了
- Vercel AI SDK 文档 — 本贯穿示例的技术栈,流式与工具调用的开箱方案
- Writing effective tools for agents — Anthropic 关于工具设计的工程实践
小结
这一章没有新知识,只有一个方法论:选一个你真实在乎的小项目,把 19 个知识点逐个钉进去并给出验收标准,用检查清单从 Demo 扛到上线,再用 badcase 驱动的迭代让它真正变好。 路线走完了,但你的第一个真实项目才刚开始——那才是学习的本体。