# AI 编程 Agent 究竟是如何工作的：一次源码深度剖析

> 我们追踪了 Amazon Q CLI 和 Claude Code 的源代码，深入理解 AI 编程 Agent 底层的真实运作方式。

- 作者: zhuermu
- 发布: 2026-03-15
- 网页版: https://zhuermu.com/blog/ai-coding-agent-internals/
- 首发于: https://mp.weixin.qq.com/s/IPOnvIXWhv1fPqC0CWlpeg

---
Cursor、Claude Code、Amazon Q、Windsurf…… 到了 2026 年，AI 编程已经成为一片竞争白热化的红海。但你有没有想过：这些工具在底层究竟是怎么工作的？

本文基于两个开源项目的源代码 —— **Amazon Q Developer CLI**（用 Rust 实现）和 **Claude Code**（TypeScript + Python）—— 从最底层拆解 AI 编程 Agent 的核心架构。

---

## 1. 先说清楚：AI 编程不是聊天机器人

很多人以为 AI 编程工具不过是给 ChatGPT 套了个 IDE 的外壳。这从根本上就错了。

聊天机器人只会*说话*，AI 编程 Agent 却能*行动*。区别在哪？**工具使用**（Tool Use，即 function calling）。

当你让 Claude Code 修一个 bug 时，幕后实际发生的是这样一串过程：

```
You:        "Fix the bug in src/app.js"
LLM thinks: I need to read that file first
LLM output: tool_call → fs_read("src/app.js")
Agent:      executes read → returns file content to LLM
LLM thinks: Found it — line 42 has the issue
LLM output: tool_call → fs_write("src/app.js", ...)
Agent:      executes write → returns result
LLM:        "Done. The problem was..."
```

这个过程被称为 **Agent 循环（Agent Loop）**—— 它是每一款 AI 编程工具中最重要的设计模式。

**关键概念：** LLM 从不直接操作你的机器。它发送结构化的 JSON 请求，告诉 Agent“我想做什么”，而 Agent 在真正代其执行之前会先校验权限。这让每一次操作都可审计、可拦截、可回滚。

---

## 2. Agent 循环：一台优雅的状态机

Amazon Q CLI 用 Rust 实现了一个显式的有限状态机来管理整个 Agent 循环。

这个状态机有**六个状态**：`Idle` → `ExecutingRequest` → `ExecutingHooks` → `WaitingForApproval` → `ExecutingTools` →（循环回到起点）

这台状态机有几处设计尤为精妙：

- **循环是自动的** —— LLM 调用工具后，结果会被重新注入对话中，并自动再次调用 LLM。
- **工具可以并行执行** —— LLM 可以在一次响应中返回多个 `tool_use` 块，Agent 使用 Tokio 的 `FuturesUnordered` 来并发执行它们。
- **每一次工具调用都要经过权限检查** —— 没有例外。

---

## 3. 工具系统：AI 的手和脚

一个 AI 编程 Agent 的能力上限，完全取决于它能访问哪些工具。

### 工具描述的艺术

工具的 `description` 不是写给人看的文档 —— 它是写给 LLM 看的行为指令。它的质量直接决定了 Agent 的表现好坏。

### `__tool_use_purpose`：逼迫 AI 在动手前先思考

Amazon Q CLI 有一个优雅的设计细节：每一次工具调用都强制要求 LLM 填写一个 `purpose` 字段。这个看似不起眼的约束效果显著 —— 它迫使模型在调用工具之前先阐明*为什么*要调用它，从而减少了幻觉式或不必要的工具调用。

---

## 4. 安全模型：四层纵深防御

AI 编程 Agent 能直接访问你的文件系统、终端和网络。安全不是可选项 —— 它是架构层面的问题。

Amazon Q CLI 实现了一套**四层安全架构**：Hook → 用户确认 → 路径权限 → 工具白名单

所有文件路径都会先经过 `canonicalize` 规范化处理，这能防止 `../` 之类的路径穿越攻击绕过权限边界。

Claude Code 则采取了另一种思路，使用 **Hook 系统**来实现声明式的安全策略，自动检测九类常见的安全风险。

---

## 5. 上下文窗口管理：最稀缺的资源

在传统软件中，瓶颈是 CPU、内存和 I/O。而在 AI 编程中，瓶颈是**上下文窗口**。

每一个 token 都很重要。系统提示词、对话历史、工具描述、文件内容以及工具返回结果，都在争抢一个固定大小窗口中的空间。一旦超出限制，模型要么丢失关键上下文，要么请求彻底失败。

Amazon Q CLI 采用四种策略来管理它：

1. **自动压缩（Auto-compaction）** —— 当窗口被填满时，把 20 万 token 的对话压缩成约 2K token 的摘要。
2. **消息截断** —— 读取大文件时，只保留前 10,000 个字符。
3. **历史裁剪** —— 保留最近的消息，同时维护结构完整性（确保工具调用/结果成对匹配）。
4. **资源文件上限** —— 自动纳入的资源文件（如 `.qdeveloper` 配置）被限制在 10KB 以内。

---

## 6. MCP 协议：工具扩展的事实标准

两个项目都采用了 **MCP（Model Context Protocol，模型上下文协议）**作为它们的工具扩展协议。MCP 提供了一种标准化方式，可以在不修改 Agent 核心代码的前提下为其添加新工具 —— 工具被定义为通过明确定义的协议进行通信的外部服务器。

Amazon Q CLI 使用 **Actor 模型**来管理多个 MCP 服务器，其中每个 MCP 服务器都作为一个拥有独立生命周期的 actor 运行。这提供了天然的隔离性：如果某个 MCP 服务器崩溃，也不会拖垮其他服务器。

---

## 7. 插件架构：Claude Code 的五维扩展模型

Claude Code 定义了**五个正交的扩展点**，让插件作者能对 Agent 行为的不同方面进行细粒度的控制。

最有意思的例子是 `feature-dev` 插件的**七阶段工作流** —— 它会并行启动多个子 Agent，同时探索不同的代码路径。每个子 Agent 在自己的探索分支上运作，最终结果被综合成一份连贯的实现方案。这是一种真正的多 Agent 模式，而不只是顺序的工具调用。

---

## 8. 架构对比

| 维度 | Amazon Q CLI | Claude Code |
|-----------|-------------|-------------|
| 语言 | Rust | TypeScript + Python |
| 架构 | 单体 Agent + Actor 并发 | 核心引擎 + 插件生态 |
| 并发 | Tokio 异步 + Actor 模型 | Node.js 事件循环 + 子进程 |
| 扩展 | MCP + Hook 脚本 | 五维插件系统 |
| 状态 | SQLite 持久化 | 文件系统 + 会话状态 |
| 优势 | 性能、类型安全 | 开发速度、丰富的生态 |

尽管存在这些表面上的差异，**核心范式却是完全一致的**：LLM Agent + 工具使用 + 流式输出 + 安全 + MCP。

这种趋同并非巧合。这些正是在真实世界的编程任务中经受住考验、存活下来的设计模式。每一款严肃的 AI 编程工具，无论用什么语言实现，最终都会以惊人相似的方式去解决同样的根本问题。

---

## 9. 七条设计原则

在深入研究了这两个代码库之后，以下是定义现代 AI 编程 Agent 构建方式的七条原则：

1. **LLM 是大脑，工具是手脚。** 模型负责推理和决策，工具负责执行。切勿混淆二者。
2. **流式优先。** 每一次交互都实时流式传输 token 和事件。批量式的请求-响应对开发者体验而言是行不通的。
3. **安全是架构问题，而非一项功能。** 权限检查、路径校验和用户确认被内建进 Agent 循环本身 —— 而不是事后再补上去的。
4. **上下文窗口是最稀缺的资源。** 每一项设计决策 —— 从工具结果的格式化到对话历史的管理 —— 都必须考虑上下文预算。
5. **工具描述就是提示词。** 工具 description 字段里的文字实际上就是系统提示词的一部分，要以同样的用心去撰写。
6. **MCP 标准化了工具生态。** 一套共享协议意味着工具可以在不同 Agent 之间移植，正如 REST 标准化了 Web API 一样。
7. **状态机驱动对话管理。** 显式的状态转换让 Agent 循环变得可预测、可调试、更安全。

---

## 结语

AI 编程看起来像魔法。但把它拆开来看，本质却出奇地简单：**一个循环、一组工具、一套权限系统**。

循环调用 LLM，LLM 挑选一个工具，工具执行，结果再反馈回循环。如此反复，直到任务完成。所有的复杂性 —— 流式输出、安全、上下文管理、插件系统 —— 都不过是围绕这个核心循环的展开与精细化。

理解这些内部机制，不只是满足好奇心。它给了你一套框架，去评估该采用哪些工具、如何扩展它们，以及真正的技术护城河在哪里（提示：护城河更多不在于循环本身，而在于工具和提示词）。

**参考项目：**
- [Amazon Q Developer CLI](https://github.com/aws/amazon-q-developer-cli) (Rust)
- [Claude Code](https://github.com/anthropics/claude-code) (TypeScript + Python)

---

## 常见问题

### 像 Claude Code 这样的 AI 编程 Agent 究竟是如何工作的？

它们运行一个 Agent 循环：LLM 读取上下文，决定调用哪个工具（读文件、写文件、执行命令），Agent 执行该操作并返回结果，然后 LLM 决定下一步，如此往复直到任务完成。

### LLM 中的工具调用（function calling）是什么？

工具调用让 LLM 输出结构化的 JSON 来请求执行某个动作（比如读取文件），而不是输出纯文本。宿主应用执行该动作，并把结果返回给 LLM 用于下一步。

### 上下文窗口如何影响 AI 编程 Agent？

上下文窗口限制了 Agent 一次能“看到”多少代码。面对大型代码库时，Agent 会采用摘要压缩、选择性读取文件、上下文压缩等策略，在这个限制内工作。

### Claude Code 和 Amazon Q Developer CLI 有什么区别？

Claude Code 使用 TypeScript，采用基于 diff 的编辑方式，默认使用 Opus 4.6。Amazon Q CLI 用 Rust 编写，采用显式的状态机架构。两者都使用相同的 Agent 循环模式，但在工具设计和权限模型上有所不同。

### AI 编程 Agent 能从零写出一整个应用吗？

它们可以搭建项目脚手架、实现功能，但在任务定义清晰、上下文明确的情况下表现最好。复杂的架构决策、模糊的需求以及大规模重构，仍然需要人类的指导。


---

## 参考资料

- [Claude Code repository](https://github.com/anthropics/claude-code) — GitHub
- [Claude Code documentation](https://code.claude.com/docs) — Anthropic
- [Anthropic engineering blog](https://www.anthropic.com/engineering) — Anthropic
- [Model Context Protocol](https://modelcontextprotocol.io/docs) — MCP Documentation
