Skip to content

🐣 小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 一样):

  1. Loop 最简单——一个 while 循环就讲清,不用画图、不用定义节点
  2. 适合"教学"——我们要的是"让你懂 Agent 本质",Loop 最能体现本质
  3. 写代码场景最合适——我们造的是个"编程助手",写代码是探索性的,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 不就行了?"

不行,原因有二:

  1. 学习目的:拆包用,你学不到 loop 怎么写。从零写,才真懂。
  2. 强耦合现实(第 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 剩下的章节,每章一个增量:

干什么增量
25LLM 调用层能调 LLM,流式输出
26Agent 循环 ★会调工具、会循环(核心)
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,再按需长大。每一层抽象都有成本,你的需求决定该不该上。


课后实验

  1. 回答六问:拿张纸,为"你想造的 Agent"回答 24.1 的六个问题。这是你造 Agent 的需求文档。
  2. 判断范式:确认你的任务该用 Loop/Workflow/Graph 哪个。如果不是 Loop,本书的代码你得自己改造(但核心循环思想通用)。
  3. 建项目骨架:mkdir my-agent && cd my-agent && npm init -y,装好 TypeScript。准备开工。

下一章:开张准备就绪,第一步——接到大模型。我们写最小的 LLM 调用客户端。 → 第 25 章 · LLM 调用层