第一个 Agent 从 Pi 开始
第一个 Agent 从 Pi 开始
来源类型: 微信公众号文章
日期: 2026-06-02
标签: AI, OpenClaw, 记忆系统, 网络安全, 编程, 大模型
原文链接: https://mp.weixin.qq.com/s/5r2tbJCu75f75hgRwQpF-Q
摘要
学 Agent,入口经常比模型 API 更先把人卡住。 不少人第一天就去研究 memory、MCP、skills、multi-agent、Agent OS。概念都对,但落到代码实现时,最先撞上的问题往往很具体:模型怎么看文件?怎么改文件?怎么跑命令?跑错了怎么办?上下文溢出了怎么办?它说做完了,证据在哪里? 我的建议是,从 Pi[1] 这种项目看起。 Pi 在 coding-agent README 里把自己称为一个 minimal terminal coding harness。这个定位很准确。它没有停在聊天壳,也没有把几十个概念堆在一起做演示。默认情况下,它先给模型一组很小的身体能力...
核心内容
学 Agent,入口经常比模型 API 更先把人卡住。
不少人第一天就去研究 memory、MCP、skills、multi-agent、Agent OS。概念都对,但落到代码实现时,最先撞上的问题往往很具体:模型怎么看文件?怎么改文件?怎么跑命令?跑错了怎么办?上下文溢出了怎么办?它说做完了,证据在哪里?
我的建议是,从 Pi[1] 这种项目看起。
Pi 在 coding-agent README 里把自己称为一个 minimal terminal coding harness。这个定位很准确。它没有停在聊天壳,也没有把几十个概念堆在一起做演示。默认情况下,它先给模型一组很小的身体能力:read、write、edit、bash。除此之外,Pi 还内置了 grep、find、ls 这类只读检索工具,适合只读模式或按需 allowlist。
再往外,才是 session、context files、compaction、skills、extensions、TUI、RPC、SDK。
Pi 这个顺序把 Agent 的底层工程暴露得很清楚:能力不会从概念里自动长出来,它靠一层层工程边界托住。
推荐参考阅读:
- 深度解析:Harness Engineering
- Agent Memory 架构本质
- 深度解析:Claude Code 源码
- 深度解读:OpenClaw 架构及生态
- AI 操作系统:从指令到意图
- 深度解析:Codex Pet Skill
- 从 Prompt Engineering 到 Context Engineering
- 深度解析:Anthropic MCP 协议
- 顶层思维
- ...
Harness 到底补齐了什么
今天群里有人问什么是 harness,我说:凡是让 Agent 趋近于目标的一切工程化手段,都是 harness(意图 → harness 工程 → 趋近目标)。
这句话可以保留,但还不够落地。
换成工程语言,harness 做的是这些事:让模型能观察环境,能采取动作,动作前能被限制,动作后能被记录,失败后能继续修,最后能拿证据判断任务有没有完成。
用户说:“帮我修一下这个 bug。”
模型本身只能生成文本。它不会天然知道项目结构,不会真的打开文件,不会运行测试,也不会记住刚才改了什么。要让它从“建议你怎么修”走到“自己去修”,至少要补齐几件事:
- 读取项目
- 修改文件
- 执行命令
- 把工具结果送回模型
- 保存行动轨迹
- 裁剪上下文
- 拦截风险动作
- 用真实证据判断完成状态
这些加起来,就是 harness。
别把 harness 想成一个新名词。它就是模型进入真实任务后绕不开的那套工程外壳。
Pi 的价值就在这里:它把最小 coding harness 拆成了模型、loop、工具、session、上下文和扩展点。没有多余包装,骨架直接暴露出来。
先看 Pi 的分层
先别急着把 pi-mono 当成一个 CLI。它的 monorepo 分得很清楚:
- packages/ai:多 provider 的 LLM API 适配层
- packages/agent:通用 agent runtime,处理 tool calling、state、event streaming
- packages/coding-agent:终端 coding harness,也就是 pi
- packages/tui / packages/web-ui:界面层
这几个包之间的关系,大概可以看成:
Provider API
-> agent loop
-> coding tools
-> session / context / compaction
-> terminal UI / RPC / SDK
这层划分比抽象概念更容易落到工程判断上。
写 Agent 最常见的坏习惯,是把模型请求、工具执行、UI 输出、文件读写、会话存储全塞进一个函数里。刚开始能跑,后面一加权限、一加压缩、一加恢复,就会变成难以调试的隐式状态机。
Pi 的边界更清楚。模型适配是一层,agent loop 是一层,coding tools 是一层,session/context 是一层,UI 只是外围投影。
这个分层处理的都是硬问题:工具调用要不要并发?参数谁来校验?工具失败怎么回给模型?流式输出怎么给 UI?session 怎么落盘?模型看到的上下文和用户看到的界面消息是不是同一份东西?
这些问题都不能只靠 prompt 解决。
Agent 的心跳:先把 loop 写稳
从零写 Agent,先把 loop 写稳,再谈 memory 和 multi-agent。
一个最小 loop 大概长这样:
user goal
-> build context
-> call model
-> stream assistant output
-> detect tool calls
-> validate tool args
-> execute tools
-> append tool results
-> call model again
-> stop with evidence
看起来很简单,写起来全是细节。
流式输出不能只打印到屏幕。你要维护一条正在增长的 assistant message,因为 tool call 可能在流中逐步出现。
工具执行这一步也容易被低估。工具参数要校验,执行过程要能取消,结果要进入 session,错误要返回给模型。多个工具并行执行时,UI 可以按完成顺序展示,但进入下一轮模型上下文的 tool result 最好保持原始 tool call 顺序。否则同一个任务会因为工具返回速度不同,产生不同上下文,后面很难调。
Pi 的 agent core 支持 sequential 和 parallel 两种工具执行模式,还提供 beforeToolCall 和 afterToolCall 钩子。前者发生在工具实际执行前,适合做参数、路径、权限、风险动作检查;后者发生在工具结果返回后,适合做审计、截断、结构化补充和错误标记。
风险拦截适合落在 runtime 层,不能只写进 prompt。命令已经生成,路径已经解析,这时候检查比在 prompt 里写“不要做危险操作”可靠得多。
Agent 工程的第一项基本功,是把 loop 当 runtime 写。不要写成一段模型调用脚本。
工具不是函数,是合约
Pi 默认给模型的工具很朴素:read、write、edit、bash。
这四个工具刚好对应 coding agent 的基本身体能力:
- read:观察项目
- write:创建或覆盖文件
- edit:做局部修改
- bash:运行测试、构建、查看环境反馈
grep、find、ls 这类只读工具也很有用。它们看起来只是把 shell 命令拆出来,但能减少模型乱跑命令的机会,也让文件检索更可控。Pi 默认不
...(内容截断,完整内容请查看原文)
本页由自动化脚本生成,待人工审核补充