拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Pi 极简编码 Agent 实战:用 AGENTS.md 与 SYSTEM.md 打造高效 AI 编程助手

Pi 极简编码 Agent 实战:用 AGENTS.md 与 SYSTEM.md 打造高效 AI 编程助手

1. 为什么“极简”反而成了编码 Agent 的杀手锏

第一次看到 Pi 这个项目的时候,我正被一堆动辄几十个配置文件、上手要先读半小时文档的 Agent 框架折磨得够呛。那段时间我试过不少方案,有的功能确实强,但光是搞清楚“哪个文件负责哪一层上下文”就得花掉一整个下午。Pi 给我的第一感觉完全相反——它安静得有点过分,核心就围绕两个文件转:AGENTS.md和SYSTEM.md。你打开项目,几乎一眼就能看懂它想干什么。

这就是我想聊 Pi 的起点。它不是一个“功能大而全”的 Agent 框架,而是一个把极简编码 Agent这件事做到极致的工具。用一句话概括:Pi 让一个编码 Agent 的“人格”和“规则”都落在纯文本里,用 TypeScript 写成,跑起来轻、改起来快、读起来不费劲。它解决的问题很具体——当你只想让 AI 帮你改代码、跑命令、读文件,而不是搭一整套编排系统时,Pi 把中间那些噪音全砍掉了。

适合谁看?如果你写过一点 TypeScript,对 Agent 的概念有基本认知,想找一个能真正读懂、能自己动手改的编码 Agent,那 Pi 就是为你准备的。哪怕你只是好奇“一个 Agent 到底由哪些部分组成”,跟着 Pi 的结构走一遍,比看十篇概念文章都管用。下面我会从设计思路、核心文件、实操流程到踩坑经验,把它拆开讲透。

2. Pi 的整体设计与极简哲学拆解

2.1 为什么是“两个文件”而不是“一套配置体系”

大多数 Agent 框架的思路是“分层配置”:系统提示词放一处,工具定义放一处,记忆放一处,编排逻辑再放一处。好处是职责清晰,坏处是心智负担重。Pi 反其道而行,把最关键的两种东西抽出来——规则和人格。

SYSTEM.md负责“你是谁、你能做什么、你的边界在哪”,也就是系统级的行为约束;AGENTS.md负责“在这个项目里,你该怎么干活”,也就是项目级的上下文和约定。这两个文件都是 Markdown,纯文本,改完即生效,不需要重新编译,也不需要理解任何 DSL。

我个人的判断是,这个设计背后有一个很务实的假设:编码 Agent 的复杂度不应该来自框架,而应该来自任务本身。框架越薄,你越容易定位问题。当 Agent 行为不对时,你只需要问自己两个问题——是SYSTEM.md里的规则写歪了,还是AGENTS.md里的项目上下文没给够?排查路径短到几乎不需要思考。

2.2 TypeScript 选型背后的真实考量

Pi 用 TypeScript 写,这个选择值得单独说。Agent 这类工具天然要和大量结构化数据打交道:工具调用的参数、文件路径、命令输出、消息流。TypeScript 的类型系统在这里不是“锦上添花”,而是实打实的安全网。

举个具体的场景。Agent 调用一个“读文件”工具时,参数可能是{ path: string },也可能是{ file: string, encoding?: string }。如果没有类型约束,这种不一致往往要到运行时才炸,而且报错信息通常很模糊。TypeScript 能在编码阶段就把这类问题拦下来。另外,现在主流的模型 SDK 和工具库对 TypeScript 的支持都相当成熟,类型定义基本开箱即用,省去了大量手写适配的工作。

提示:如果你打算基于 Pi 做二次开发,先把tsconfig.json里的strict打开。Agent 项目里类型宽松带来的隐患,远比普通业务代码要大,因为很多错误发生在“模型返回的字符串”和“你期望的结构”之间。

2.3 极简不等于简陋:被保留的核心能力

有人会误以为“极简”就是功能少。Pi 砍掉的是配置的复杂度,但编码 Agent 该有的核心能力一个没少:读写文件、执行命令、多轮对话、上下文管理。它只是把这些能力用最直接的方式暴露出来,而不是包一层又一层的抽象。

我实测下来最舒服的一点是,Pi 的工具调用链路非常短。你让它改一个文件,它不会先经过“规划器”再经过“执行器”再经过“校验器”,而是直接读、直接改、直接给你看结果。这种直接性在调试阶段特别有价值——出问题时你能清楚看到是哪一步偏了,而不是在一堆中间层里猜。

3. 核心文件深度解析:AGENTS.md 与 SYSTEM.md

3.1 SYSTEM.md:给 Agent 立规矩的地方

SYSTEM.md是 Agent 的“宪法”。它决定了 Agent 的基本行为模式:说话风格、是否主动执行命令、遇到不确定时是追问还是猜测、能碰哪些文件、不能碰哪些文件。写得好,Agent 就像一个靠谱的同事;写得糊,它就会变成一个自作主张的麻烦制造者。

我一般会在这个文件里放三类内容。第一类是身份与语气,比如“你是一个专注于代码修改的助手,回答简洁,不废话”。第二类是行为边界,比如“修改文件前先说明你要改什么”“不要执行任何删除操作”。第三类是失败处理,比如“如果命令报错,先读错误信息再决定下一步,不要盲目重试”。

这里有个很多人忽略的细节:SYSTEM.md里的规则要可判定。什么叫可判定?就是 Agent 能明确知道自己有没有违反。“回答要友好”这种就不可判定,“回答不超过三句话”就可判定。规则越可判定,Agent 的行为越稳定。

3.2 AGENTS.md:项目级的上下文契约

如果说SYSTEM.md是通用规则,那AGENTS.md就是“这个项目专属的说明书”。它通常放在项目根目录,Agent 启动时会读取它,从而知道这个项目的技术栈、目录结构、编码规范、常用命令。

我见过写得最好的AGENTS.md,内容大致长这样:项目用什么包管理器、测试怎么跑、代码风格是什么、哪些目录是自动生成的不要动、提交信息用什么格式。这些信息如果每次都靠人临时告诉 Agent,效率极低还容易漏。写进AGENTS.md,等于给 Agent 装了一份“入职手册”。

下面是一个我常用的AGENTS.md骨架,你可以直接抄:

# 项目上下文 ## 技术栈 - 语言:TypeScript 5.x - 运行时:Node.js 20 - 包管理:pnpm ## 常用命令 - 安装依赖:pnpm install - 运行测试:pnpm test - 类型检查:pnpm typecheck ## 编码规范 - 使用 2 空格缩进 - 优先使用 const,避免 var - 所有导出函数必须有返回类型标注 ## 禁止事项 - 不要修改 dist/ 目录下的任何文件 - 不要提交 .env 文件

3.3 两个文件如何协同:一次真实的上下文流转

理解这两个文件的关系,最好的方式是跟一遍真实流程。假设你对 Pi 说“帮我把 utils 里的日期格式化函数改成支持时区”。

Agent 启动时先读SYSTEM.md,知道自己“修改前要先说明、不能碰敏感文件”。然后读AGENTS.md,知道这个项目用 pnpm、测试命令是pnpm test、代码要 2 空格缩进。接着它去读utils目录,找到那个函数,按项目规范改完,再跑一次测试确认没破坏别的东西。

整个过程里,SYSTEM.md管的是“怎么做事”,AGENTS.md管的是“在这个项目里怎么做事”。两者分工明确,互不干扰。这也是为什么 Pi 的排查特别简单——行为不对,先看SYSTEM.md;项目相关的错误,先看AGENTS.md。

4. 从零跑通一个 Pi 编码 Agent 的完整实操

4.1 环境准备与依赖安装

先把基础环境搭起来。你需要 Node.js 20 或更高版本,包管理器用 pnpm 会更顺(npm 也能跑,但 pnpm 在依赖体积上优势明显)。确认版本:

node -v pnpm -v

如果 pnpm 没装,用npm install -g pnpm装上。然后拉取项目、安装依赖:

git clone <项目地址> cd pi pnpm install

安装完成后,先跑一次类型检查,确认环境没问题:

pnpm typecheck

这一步很关键。很多人跳过它直接跑,结果遇到一堆运行时错误,其实是依赖没装全或者版本不匹配。类型检查能在几秒内把这些基础问题暴露出来。

4.2 配置 SYSTEM.md 与 AGENTS.md

环境好了,接下来是配置。先在项目根目录创建SYSTEM.md,内容按你的需求写。我建议第一版尽量简单,先跑通再加规则:

# 角色 你是一个编码助手,专注于修改和解释代码。 # 行为准则 - 修改文件前,先用一句话说明你要改什么 - 执行命令后,简要说明结果 - 遇到错误时,先读错误信息,不要盲目重试 - 不确定时,先问,不要猜

然后创建AGENTS.md,把项目的基本信息填进去。如果你只是拿 Pi 做实验,可以先用一个最小版本:

# 项目上下文 ## 技术栈 - TypeScript ## 常用命令 - 类型检查:pnpm typecheck

注意:两个文件都必须是 UTF-8 编码。我踩过一次坑,用某个编辑器保存成了带 BOM 的格式,结果 Agent 读到的第一行多了几个不可见字符,行为直接跑偏,排查了半天才发现是编码问题。

4.3 启动与第一次对话

配置就绪,启动 Agent:

pnpm start

启动后,先做一次最简单的交互测试,比如让它读一个文件:

读一下 package.json,告诉我这个项目用了哪些依赖

观察它的行为。如果它直接读了文件并给出总结,说明基础链路通了。如果它开始胡言乱语或者报错,先检查SYSTEM.md是不是写得太复杂导致模型理解困难。我的经验是,第一版规则越少越好,跑通之后再逐步加约束。

4.4 一次完整的代码修改任务实录

跑通基础对话后,来一个真实任务。假设项目里有个formatDate函数,你想让它支持时区参数。你可以这样说:

utils/date.ts 里的 formatDate 函数,帮我加一个可选的 timezone 参数, 默认用本地时区。改完跑一下类型检查。

一个配置良好的 Pi Agent 会这样执行:先读utils/date.ts,找到函数,说明它打算怎么改,改完后运行pnpm typecheck,最后把结果告诉你。整个过程你能清楚看到每一步,而不是黑箱。

这里有个实操心得:任务描述里带上验证方式。比如“改完跑类型检查”“改完跑测试”,Agent 就会主动验证,而不是改完就停。这一个小习惯能帮你省掉大量“改完才发现坏了”的时间。

5. 常见问题与排查技巧实录

5.1 Agent 行为跑偏了怎么办

这是最高频的问题。Agent 不按你期望的方式行动,通常有三个原因。第一,SYSTEM.md里的规则互相矛盾,比如既说“主动执行”又说“先问再做”。第二,规则太抽象,Agent 无法判定。第三,AGENTS.md里的项目信息和实际不符,导致它基于错误前提行动。

排查顺序建议是:先看SYSTEM.md有没有矛盾规则,再看规则是否可判定,最后核对AGENTS.md是否准确。我遇到过最隐蔽的一次,是AGENTS.md里写的测试命令是旧的,Agent 每次跑测试都失败,然后开始“自作聪明”地改测试文件。核对命令后问题立刻消失。

5.2 命令执行失败与错误信息处理

Agent 执行命令失败时,最常见的错误反应是“盲目重试”。同一个命令重试三次,结果当然一样。好的SYSTEM.md应该明确要求它“先读错误信息”。如果它还是重试,说明规则没写到位,可以加一条更硬的约束:“命令失败后,禁止在未说明失败原因前重试”。

另外,有些命令失败是因为环境问题,比如依赖没装、路径不对。这类问题 Agent 自己解决不了,需要你介入。所以我在SYSTEM.md里会加一条:“如果错误涉及环境或依赖,停下来告诉我,不要尝试自行修复。”

5.3 上下文丢失与长任务处理

长任务里,Agent 容易“忘记”前面的约定。这不是 Pi 独有的问题,而是所有 Agent 的通病。缓解办法有两个:一是把关键约定写进AGENTS.md,让它每次都能读到;二是在长任务中主动提醒,比如“记住,这个项目用 2 空格缩进”。

下面这张表是我整理的常见问题速查,遇到问题可以直接对照:

现象可能原因排查方向
行为不符合预期SYSTEM.md 规则矛盾或抽象检查规则是否可判定
项目相关操作出错AGENTS.md 信息过时核对命令与目录结构
命令反复失败缺少失败处理规则补充“先读错误再重试”
长任务中约定丢失上下文被稀释关键约定写入 AGENTS.md
读取文件乱码文件编码非 UTF-8统一保存为 UTF-8

5.4 几个我踩过的坑

第一个坑是规则写太多。一开始我恨不得把所有情况都写进SYSTEM.md,结果 Agent 反而变得畏手畏脚,什么都不敢做。后来我砍到只剩五条核心规则,行为立刻稳定了。规则不是越多越好,而是越准越好。

第二个坑是忽略 AGENTS.md 的维护。项目结构变了、命令改了,但AGENTS.md没更新,Agent 就会基于旧信息行动。我现在养成的习惯是,只要项目有结构性变更,第一件事就是更新AGENTS.md。

第三个坑是用模糊的任务描述。“优化一下这个文件”这种指令,Agent 只能猜。改成“把这个文件里的重复逻辑抽成一个函数”,它就能准确执行。任务描述越具体,结果越可控。

6. 把 Pi 用顺手的几个进阶思路

6.1 用 AGENTS.md 做团队协作的“共识文件”

AGENTS.md的价值不止于个人使用。当团队多人共用一套 Agent 配置时,它就成了“共识文件”——大家把项目约定写进去,Agent 的行为就统一了。新人加入时,读一遍AGENTS.md就知道项目怎么跑,比口口相传靠谱得多。

我建议团队维护AGENTS.md时遵循一个原则:只写事实,不写偏好。“用 pnpm”是事实,“用 pnpm 更好”是偏好。事实类信息 Agent 能直接用,偏好类信息容易引发争议。

6.2 按任务类型拆分 SYSTEM.md 的思路

如果你的使用场景比较杂,可以考虑按任务类型准备不同的SYSTEM.md。比如一个用于“代码修改”,一个用于“代码审查”,一个用于“文档生成”。切换时替换文件即可,不需要改代码。

这样做的好处是每个SYSTEM.md都能保持精简,规则针对性强。缺点是切换需要手动操作。如果你用得多,可以写个小脚本做切换,几行代码的事。

6.3 关于 TypeScript 配置的一个提醒

前面提到过,现在有些 TypeScript 的旧配置项正在被弃用,比如baseUrl和moduleResolution=node10这类选项,在未来的大版本里会停止支持。如果你在基于 Pi 做二次开发,建议尽早把tsconfig.json迁移到新的配置方式,用paths配合现代的模块解析策略。现在改成本很低,等到被迫改的时候,可能牵涉的代码就多了。

我在实际使用 Pi 的过程中最大的体会是:Agent 好不好用,八成取决于你给它的上下文质量,而不是框架本身有多复杂。Pi 把这一点做得很诚实——它不帮你隐藏问题,而是让你直面“规则写清楚了吗、上下文给够了吗”这两个根本问题。把这两个问题解决好,一个极简的 Agent 能干的活,远比想象中多。

返回列表