第一章:Coding Agent 概述 -- 从 Agent 到编码助手产品
对应源文件:
packages/coding-agent/src/
回顾
到目前为止我们学了:
ai包:统一 LLM API,发请求收响应agent包:tool-call loop 和状态管理
这两个包加起来不到 3000 行代码,提供了"通用 AI Agent"的能力。但要变成一个可用的编码助手产品,还需要大量"产品化"的工作。
coding-agent 做了什么
coding-agent 是整个项目中最大最复杂的包(agent-session.ts 一个文件就有 103KB)。它在 agent 包之上增加了:
| 功能 | 说明 |
|---|---|
| 内置工具 | read、write、edit、bash、grep、find、ls -- 操作文件系统的完整工具集 |
| 系统提示 | 精心构建的 system prompt,告诉 AI 如何使用这些工具 |
| 扩展系统 | 通过 TypeScript 扩展添加自定义工具、命令、快捷键、UI 组件 |
| 会话管理 | JSONL 树形结构持久化对话历史,支持分支、恢复、fork |
| 上下文压缩 | 当对话超出 context window 时自动摘要和压缩 |
| 多模型支持 | 运行中切换模型,model scope 循环切换 |
| CLI | 完整的命令行界面:参数解析、四种运行模式 |
| 设置系统 | 全局 + 项目级设置,支持热加载 |
| 认证存储 | API key 和 OAuth token 管理 |
| Skills | 可复用的 prompt 指令文件 |
架构总览
用户输入
↓
CLI (cli.ts + args.ts)
↓ 解析参数
main.ts
↓ 加载配置、创建 session
AgentSession (agent-session.ts) ← 核心!
├── Agent 实例(来自 agent 包)
├── 内置工具(tools/)
├── 系统提示(system-prompt.ts)
├── 扩展系统(extensions/)
├── 会话管理(session-manager.ts)
├── 上下文压缩(compaction/)
├── 模型管理(model-registry.ts + model-resolver.ts)
└── 设置管理(settings-manager.ts)
↓
运行模式
├── Interactive(TUI 交互界面)
├── Print(非交互输出)
├── RPC(stdin/stdout JSON-RPC)
└── JSON(事件流输出)
四种运行模式
| 模式 | 触发方式 | 使用场景 |
|---|---|---|
| Interactive | 默认(终端直接运行 pi) | 主要使用方式,TUI 交互界面 |
pi -p "问题" 或管道输入 | 非交互,输出结果后退出 | |
| RPC | pi --rpc | stdin/stdout JSONL 协议,供其他程序集成 |
| JSON | pi --json "问题" | 输出全部事件为 JSON lines |
启动流程
main.ts 是一个 732 行的启动编排器,按顺序完成以下步骤:
1. 解析 CLI 参数(parseArgs)
2. 运行数据迁移(runMigrations)
3. 创建会话管理器(createSessionManager)
- 根据 --session/--resume/--continue/--fork 参数选择
4. 创建运行时服务(createAgentSessionServices)
- 加载设置(SettingsManager)
- 加载扩展、skills、themes(ResourceLoader)
- 构建模型注册表(ModelRegistry)
5. 创建 AgentSession
- 装配 Agent + tools + extensions
- 恢复历史对话
6. 读取 stdin 内容(管道输入)
7. 根据模式启动
- Interactive → new InteractiveMode(runtime).run()
- Print → runPrintMode(runtime)
- RPC → runRpcMode(runtime)
关键子系统预览
AgentSession(agent-session.ts)
这是整个 coding-agent 的核心。它:
- 创建并配置
Agent实例 - 注册所有内置工具和扩展工具
- 实现
convertToLlm(把自定义消息类型转为 LLM 消息) - 实现
transformContext(上下文压缩的集成点) - 管理模型切换
- 协调扩展系统
内置工具(tools/)
7 个核心工具覆盖了文件操作的所有方面:
| 工具 | 功能 | 代码量 |
|---|---|---|
read | 读取文件/图片,支持行范围和截断 | 274 行 |
write | 创建/覆写文件 | ~250 行 |
edit | 基于 search/replace 的精准编辑 | ~400 行 |
bash | 执行 shell 命令 | ~400 行 |
grep | 搜索文件内容(ripgrep 风格) | ~350 行 |
find | 查找文件(尊重 .gitignore) | ~320 行 |
ls | 列出目录内容 | ~200 行 |
扩展系统(extensions/)
扩展是 pi 最重要的设计决策之一。几乎所有"高级功能"都通过扩展实现:
- Sub-agent(子代理)→ 扩展
- Plan mode(计划模式)→ 扩展
- 权限弹窗 → 扩展(通过
beforeToolCall钩子) - 自定义工具 → 扩展
- 自定义快捷键和命令 → 扩展
扩展 API 类型定义有 53KB(1546 行),覆盖了:工具注册、命令注册、快捷键绑定、UI 组件、事件监听、会话控制等几乎所有方面。
会话管理(session-manager.ts)
对话历史以 JSONL(每行一条 JSON 记录)格式存储在 ~/.pi/agent/sessions/ 目录下。
关键设计:树形结构。每条记录有 id 和 parentId,形成一棵树而非线性列表。这支持:
- 分支(从历史某点创建新分支)
- Fork(从任意位置创建新会话文件)
- 导航(在不同分支间切换)
上下文压缩(compaction/)
当对话超出模型的 context window 时,自动触发压缩:
- 估算当前上下文的 token 数
- 找到合适的切割点
- 用 LLM 对旧消息生成摘要
- 用摘要替代旧消息
- 记录为 CompactionEntry 保存到 session 文件
下一步
下面几章会深入每个子系统。建议的阅读顺序:
- 内置工具(read + edit)→ 理解工具如何实现
- 系统提示 → 理解 AI 的"行为规范"
- 扩展系统 → 理解可扩展性设计
- 会话管理 → 理解持久化和分支
- 上下文压缩 → 理解 context overflow 的解决方案