# 第一章：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 交互界面 |
| **Print** | `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 时，自动触发压缩：
1. 估算当前上下文的 token 数
2. 找到合适的切割点
3. 用 LLM 对旧消息生成摘要
4. 用摘要替代旧消息
5. 记录为 CompactionEntry 保存到 session 文件

---

## 下一步

下面几章会深入每个子系统。建议的阅读顺序：

1. 内置工具（read + edit）→ 理解工具如何实现
2. 系统提示 → 理解 AI 的"行为规范"
3. 扩展系统 → 理解可扩展性设计
4. 会话管理 → 理解持久化和分支
5. 上下文压缩 → 理解 context overflow 的解决方案
