Appearance
🐣 小a出师了
Part I 学概念,Part II 拆源码。现在老z把小a领到一间空屋子:"这是你的工坊。你自己造一个 Agent。但动手前,先想清楚:你要造什么?用什么范式?带什么工具? 磨刀不误砍柴工。"
从这一章起,我们进入 Part III 实现篇——不再读 pi 的代码,而是自己用 TypeScript 从零造一个能跑的 Agent。每章一个增量,读完手里有一个真实可用的 Agent。
24.1 动手前,先问自己六个问题
老z递给小a一张问卷。造 Agent 前,这六个问题必须想清楚:
| 问题 | 为什么重要 |
|---|---|
| 我的 Agent 解决什么问题? | 决定它的"人格"和工具集 |
| 任务路径是固定的还是自由的? | 决定用 Loop 还是 Workflow(第 14 章) |
| 支持几家厂商? | 决定要不要 Provider 抽象(第 3 章) |
| 要不要持久化会话? | 决定要不要 session 层(第 18 章) |
| 给谁用?在哪跑? | 决定要不要 TUI、要不要远程(第 19/21 章) |
| 数据能上云吗? | 决定本地还是云端(附录 F) |
🧙 为什么先问这些?
因为每一层抽象都有成本(这是本书反复的主题)。不加思考地"全上",会造出一个臃肿的怪物;什么都不加,又会处处掣肘。你的需求,决定该上哪些层。
24.2 范式选择:Loop、Workflow 还是 Graph?
第 14 章讲过三种范式。现在轮到我们做选择了。
🧙 决策树:
你的任务,下一步由谁决定? │ ├─ 模型自己看着办(探索性、创造性) │ → Loop(本书的选择,和 pi 一样) │ ├─ 步骤预先写死(审批、ETL) │ → Workflow │ └─ 复杂多分支、需条件路由 → Graph
我们选 Loop,为什么?
🧙 本书选 Loop 的理由(和 pi 一样):
- Loop 最简单——一个 while 循环就讲清,不用画图、不用定义节点
- 适合"教学"——我们要的是"让你懂 Agent 本质",Loop 最能体现本质
- 写代码场景最合适——我们造的是个"编程助手",写代码是探索性的,Loop 最贴切
代价:Loop 不可预测(同样输入可能不同输出)。但我们接受,换取灵活性。
🐣 小a记下:"所以我们造的 Agent,骨架就是一个循环。不搞 Workflow,不搞 Graph,不搞 RAG。先把最简单的 Loop 跑通,再考虑要不要加复杂的。"
🧙 "对!这就是 YAGNI(You Aren't Gonna Need It)——你暂时不需要的,就别提前做。"
24.3 工具栈:极简主义
我们用什么技术栈?老z给小a定了极简原则:
| 选择 | 为什么 |
|---|---|
| Node.js + TypeScript | 和 pi 同栈,学到的能直接对照 |
| 原生 fetch | 调 LLM API,不引 SDK,看清本质 |
| 不引框架 | 不用 LangChain 之类的,自己写循环 |
| 先用 1 家厂商 | 先 Anthropic(或 OpenAI),不做 Provider 抽象 |
🧙 为什么这么"省"?
因为我们的目标是理解本质,不是"造一个产品级框架"。每引一个依赖,就多一层"黑盒"——你看不清底层在干什么。
裸 fetch 调 API,你能看到每一个 HTTP 请求长什么样。这种"透明"是学习的关键。
等你理解了本质,再考虑要不要上框架(那时你能判断框架帮你省了什么、又掩盖了什么)。
24.4 一个重要的诚实声明:我们不复用 pi 的代码
老z必须对小a(和读者)说实话:
🧙 诚实声明:我们从零写,不拆 pi 的包来复用。
你可能想:"pi-agent-core 不是现成的吗?直接
npm install用它的 loop 不就行了?"不行,原因有二:
- 学习目的:拆包用,你学不到 loop 怎么写。从零写,才真懂。
- 强耦合现实(第 18 章讲过):pi-agent-core 强依赖 pi-ai。你想"只拿 loop 不拿 ai",做不到——它俩绑在一起。硬拆会用不了。
所以我们借鉴 pi 的思想,但从零写自己的代码。 这样你得到的是"可独立理解、可自由修改"的 Agent,不是"被 pi 类型体系绑住"的。
24.5 我们要造的 Agent:长什么样
明确目标。读完 Part III,你手里会有一个这样的 Agent:
我的 Agent(my-agent/)
├── 能调 1 家 LLM(Anthropic 或 OpenAI)
├── 有一个 Agent 循环(~80 行核心)
├── 带 3 个工具:read / write / bash
├── 能记会话(JSONL 存盘)
├── print 模式输出(行输出,最简)
├── 基础安全(路径白名单 + 危险命令确认)
└── 总代码 ~500 行不是 pi 那个量级(pi 是几万行),但五脏俱全——你能看到 Agent 的每个零件是怎么运转的。而且它真能跑——能帮你读文件、改代码。
🐣 小a问:"才 500 行?够用吗?"
🧙 "对绝大多数个人需求,500 行的 Agent 足够了。 pi 之所以几万行,是因为它要服务百万用户、支持几十家厂商、跑在多种环境——那些复杂性,你不需要。先造一个能跑的小家伙,再按需长大。"
24.6 接下来的路线图
Part III 剩下的章节,每章一个增量:
| 章 | 干什么 | 增量 |
|---|---|---|
| 25 | LLM 调用层 | 能调 LLM,流式输出 |
| 26 | Agent 循环 ★ | 会调工具、会循环(核心) |
| 27 | 工具系统 | read/write/bash 三个工具 |
| 28 | 上下文与会话 | 滑动窗口 + JSONL 存盘 |
| 29 | 交互层 | print 模式,能人机对话 |
| 30 | 安全与扩展 | 路径白名单 + 危险命令确认 |
| 31 | 让它长大 | 何时加 Provider/MCP/多 Agent |
| 32 | 收官 | 拼成完整产物,跑起来 |
本章小结
🐣 小a的第二十四课(Part III 开篇)
┌──────── 开张准备 ────────┐ │ │ │ • 动手前先想清六问 │ │ (需求/范式/厂商/...) │ │ │ │ • 范式选 Loop(YAGNI) │ │ 不搞 Workflow/Graph │ │ │ │ • 工具栈极简: │ │ Node+TS+fetch │ │ 不引框架,看清本质 │ │ │ │ • 从零写,不复用 pi 包 │ │ (强耦合 + 学习目的) │ │ │ │ • 目标:~500 行能跑的 │ │ Agent,五脏俱全 │ └──────────────────────────┘
核心思想:YAGNI——你暂时不需要的,就别提前做。先造一个最简单的能跑的 Agent,再按需长大。每一层抽象都有成本,你的需求决定该不该上。
课后实验
- 回答六问:拿张纸,为"你想造的 Agent"回答 24.1 的六个问题。这是你造 Agent 的需求文档。
- 判断范式:确认你的任务该用 Loop/Workflow/Graph 哪个。如果不是 Loop,本书的代码你得自己改造(但核心循环思想通用)。
- 建项目骨架:
mkdir my-agent && cd my-agent && npm init -y,装好 TypeScript。准备开工。
下一章:开张准备就绪,第一步——接到大模型。我们写最小的 LLM 调用客户端。 → 第 25 章 · LLM 调用层