综合编码 Agent - 纯 Python 实现


文档摘要

源文件:chapter5/coding-agent/README.md 综合编码 Agent - 纯 Python 实现 一个基于 Claude 构建、面向生产的 AI 编码 Agent,用纯 Python 工具实现了第 2 章的全部技术——无需任何命令行依赖! 核心特性 纯 Python 实现 所有工具都不依赖任何命令行工具: 无需 、 (ripgrep)、 命令 不依赖任何系统工具 100% 纯 Python 实现 在任何装有 Python 3.8+ 的系统上都能运行 尤其适合没有命令行工具的 Mac 用户 完整工具套件 tools.

源文件:chapter5/coding-agent/README.md

综合编码 Agent - 纯 Python 实现

一个基于 Claude 构建、面向生产的 AI 编码 Agent,用纯 Python 工具实现了第 2 章的全部技术——无需任何命令行依赖!

核心特性

纯 Python 实现

所有工具都不依赖任何命令行工具:

  • 无需 greprg(ripgrep)、find 命令
  • 不依赖任何系统工具
  • 100% 纯 Python 实现
  • 在任何装有 Python 3.8+ 的系统上都能运行
  • 尤其适合没有命令行工具的 Mac 用户

完整工具套件

tools.json 中的全部 16 个工具均已完整实现:

文件操作(纯 Python):

  • Read - 文件读取,支持图像 / PDF / notebook
  • Write - 文件写入,带自动 lint 检查
  • Edit - 查找并替换编辑
  • MultiEdit - 一次操作中完成多处编辑

搜索工具(纯 Python,不依赖 rg/grep):

  • Grep - 纯 Python 正则检索,与 ripgrep 功能完全对齐
    • 完整正则支持
    • 大小写不敏感检索
    • 上下文行(前 / 后 / 前后)
    • 行号
    • 多行模式
    • Glob 过滤
    • 文件类型过滤
    • 多种输出模式
  • Glob - 文件模式匹配
  • LS - 目录列表

Shell 操作:

  • Bash - 持久化 shell 会话
  • BashOutput - 后台任务输出
  • KillBash - 终止 shell

项目管理:

  • TodoWrite - 任务列表管理
  • ExitPlanMode - 退出计划模式

高级:

  • NotebookEdit - Jupyter notebook 编辑
  • WebFetch - 网页内容抓取(桩实现)
  • WebSearch - 网页检索(桩实现)
  • Task - 子 Agent 启动器(桩实现)

系统提示技术(第 2 章)

  1. 时间戳:每条消息和工具结果都带时间戳
  2. 工具调用计数:3 次以上重复调用时告警
  3. TODO 列表管理:显式的任务跟踪
  4. 详细错误信息:丰富的错误上下文
  5. 系统状态感知:工作目录、操作系统、Python 版本
  6. 环境信息:上下文中的动态状态

终端环境

  • 持久化 shell 会话:命令在同一 shell 中执行
  • 工作目录跟踪:目录变更被保留
  • 后台执行:支持长时间运行的命令

自动 lint 检测

在 Write/Edit/MultiEdit 之后:

  • Python 语法检查
  • JavaScript/TypeScript 检查
  • 错误立即出现在工具结果中

项目结构

coding-agent/ ├── agent.py # 主 Agent 实现 ├── system_state.py # 系统状态跟踪 ├── tool_registry.py # 工具名 → 实现的映射 ├── tools/ # 所有工具实现 │ ├── __init__.py │ ├── base.py # 基础工具类 │ ├── bash_tool.py # Shell 执行 │ ├── bash_output_tool.py # 后台任务输出 │ ├── kill_bash_tool.py # Shell 终止 │ ├── read_tool.py # 文件读取 │ ├── write_tool.py # 文件写入 │ ├── edit_tool.py # 文件编辑 │ ├── multi_edit_tool.py # 多处编辑 │ ├── grep_tool.py # 纯 Python 正则检索(无需 rg!) │ ├── glob_tool.py # 文件模式匹配 │ ├── ls_tool.py # 目录列表 │ ├── todo_write_tool.py # TODO 管理 │ ├── exit_plan_mode_tool.py │ ├── notebook_edit_tool.py │ ├── web_fetch_tool.py │ ├── web_search_tool.py │ ├── task_tool.py │ └── shell_session.py # Shell 会话管理 ├── tools.json # 工具定义 ├── system-prompt.md # 系统提示 ├── config.py # 配置 ├── requirements.txt # 依赖 └── README.md # 本文件

安装

# 进入项目目录 cd /Users/boj/ai-agent-book/projects/week5/coding-agent # 安装依赖 pip install -r requirements.txt # 配置环境 cp .env.example .env # 编辑 .env 并配置你的提供商

配置

编辑 .env 文件:

# 选择你的提供商(anthropic、openai 或 openrouter) PROVIDER=anthropic # 为所选提供商添加 API 密钥 ANTHROPIC_API_KEY=sk-ant-api03-... # 或 OPENROUTER_API_KEY=sk-or-v1-... # 或 OPENAI_API_KEY=sk-... # 为所选提供商选择合适的模型 DEFAULT_MODEL=claude-sonnet-5

详细的提供商配置指南见 PROVIDERS.md。

依赖要求

核心依赖:

  • Python 3.8+
  • anthropic - 用于 Anthropic API
  • openai - 用于 OpenAI/OpenRouter API
  • python-dotenv - 用于配置

可选(用于增强功能):

  • PyPDF2 - 用于 PDF 读取
  • requestsbeautifulsoup4html2text - 用于 WebFetch

无需任何命令行工具! 在没有 Homebrew 包的 macOS 上也能运行。

受支持的提供商

  • Anthropic - 直连 Claude API
  • OpenRouter - 访问 Claude、GPT、Gemini、Llama 等
  • OpenAI - 直连 GPT API

Agent 会自动处理各提供商不同的 API 格式。

将 OpenRouter 作为通用回退

无需直接的 Anthropic 或 OpenAI 密钥就能运行 Agent。如果
所请求的直连提供商密钥缺失,只要设置了
OPENROUTER_API_KEY,Agent 就会透明地回退到
OpenRouter(经由 OpenAI 兼容 SDK):

  • PROVIDER=anthropic 且有 ANTHROPIC_API_KEY → Anthropic SDK,行为不变(默认)。
  • PROVIDER=anthropic 但无 ANTHROPIC_API_KEY(且设置了 OPENROUTER_API_KEY)→ 经由 OpenRouter 路由。
  • PROVIDER=openai 且有 OPENAI_API_KEY → OpenAI SDK,行为不变。
  • PROVIDER=openai 但无 OPENAI_API_KEY(且设置了 OPENROUTER_API_KEY)→ 经由 OpenRouter 路由。

回退时,原生模型 id 会被加前缀 / 映射为 OpenRouter id:

请求的模型 使用的 OpenRouter id
claude-sonnet-*(如 claude-sonnet-5 anthropic/claude-sonnet-4.6
claude-haiku-* anthropic/claude-haiku-4.5
claude-opus-* / 其他 claude-* anthropic/claude-opus-4.8
gpt-* / o1-*(如 gpt-5.6-luna openai/<model>
已带前缀(vendor/model 原样透传

因此,一个只有 OPENROUTER_API_KEY 的用户也能运行,例如:

# 无需 ANTHROPIC_API_KEY——自动回退到 OpenRouter python main.py --provider anthropic --model claude-sonnet-5 -p "..." # gpt-5.6-luna 经由 OpenRouter 路由(无需 OPENAI_API_KEY) python main.py --provider openai --model gpt-5.6-luna -p "..."

如果你想在不做任何映射的情况下指定某个 OpenRouter 模型,可显式设置
PROVIDER=openrouter(并使用 vendor/model 形式的 id)。

用法

命令行入口(main.py

main.py 是唯一推荐的入口,提供统一的 argparse 命令行界面。运行
python main.py --help 查看完整的中文帮助:

python main.py --help

主要参数:

参数 说明
(无参数) 进入交互式对话(默认行为)
-p, --prompt "任务" 非交互模式:执行单个任务后退出,适合脚本 / CI
--list-tools 离线列出全部已注册工具及简介(无需 API Key,可用于自检)
--provider {anthropic,openai,openrouter} 临时覆盖 .env 中的 PROVIDER
--model 模型名 临时覆盖 .env 中的 DEFAULT_MODEL
--base-url URL 临时覆盖 API Base URL(自建网关 / 兼容 OpenAI 的服务)
--max-iterations N 单个任务的最大 Agent 迭代轮数(默认 50)
--no-color 禁用彩色输出(无 TTY 时自动禁用)

快速自检(离线,无需 API Key)

先确认工具集加载正常:

$ python main.py --list-tools 共 16 个工具: Task Launch a new agent to handle complex, multi-step tasks autonomously. Bash Executes a given bash command in a persistent shell session ... Glob - Fast file pattern matching tool that works with any codebase size Grep A powerful search tool built on ripgrep ...

端到端示例:让 Agent 完成一个真实编码任务

配置好 .env(见上文 Configuration)后,用一条命令让 Agent 创建并运行一个脚本:

python main.py -p "创建 hello_world.py:打印 Hello, World!,包含一个按姓名问候的函数和一个 main 演示块,然后运行它验证输出。"

成功时的终端输出结构大致如下(示意,实际轮次/调用次数取决于模型):

✓ Agent initialized successfully You: 创建 hello_world.py ... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🔧 Calling tool: Write ✓ Completed (call #1) ✓ No lint errors File: hello_world.py 🔧 Calling tool: Bash ✓ Completed (call #2) Output: Hello, World! Hello, Alice! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Task completed! Iterations: 2 Tool calls: 2

判定成功的标志:Agent 依次调用 Write 写文件、Bash 运行脚本,
终端出现脚本的真实输出,并以 ✅ Task completed! 收尾。
quickstart.py 是同一任务的脚本化版本,可作对照。)

交互式对话(默认)

不带 -p 直接运行即进入交互式会话:

python main.py

特性:

  • 彩色输出,提升可读性
  • 实时流式响应
  • 工具执行的实时展示
  • 内置状态命令
  • 对话历史
  • reset 命令可重新开始

会话内命令(在对话中输入):

  • /help - 显示帮助信息
  • /quit/exit - 退出 CLI
  • /reset - 重置对话历史
  • /clear - 清屏
  • /status - 显示 Agent 状态(工具调用、TODO 等)

其他示例脚本(均需 API Key)

python quickstart.py # 基础快速上手(与上文端到端示例同款任务) python example_complex_task.py # 复杂多步任务 python example_with_system_hints.py # 系统提示(System Hint)技术演示

编程式用法

from agent import CodingAgent agent = CodingAgent(api_key="your-key") for event in agent.run("List all Python files"): if event["type"] == "text_delta": print(event["delta"], end="", flush=True) elif event["type"] == "done": print("\n✅ Done!")

纯 Python Grep 实现

Grep 工具完全用纯 Python 实现,不依赖任何 greprg 或其他命令行工具。它提供了 ripgrep 的全部功能:

# 示例:在文件中检索模式 { "name": "Grep", "input": { "pattern": "def.*test", "path": "/path/to/search", "output_mode": "content", "-i": True, # 大小写不敏感 "-C": 3, # 3 行上下文 "-n": True, # 显示行号 "glob": "*.py", # 仅 Python 文件 "multiline": False # 单行匹配 } }

特性:

  • 完整正则支持(Python re 模块)
  • 大小写不敏感检索(-i
  • 上下文行(-A-B-C
  • 行号(-n
  • 多行模式
  • Glob 过滤(glob 参数)
  • 文件类型过滤(type 参数)
  • 输出模式:contentfiles_with_matchescount
  • 头部限制
  • 递归目录检索
  • 跳过二进制文件
  • 跳过隐藏文件 / 目录

架构

模块化工具系统

每个工具都实现为继承自 BaseTool 的独立类:

class MyTool(BaseTool): @property def name(self) -> str: return "MyTool" def _execute_impl(self, params: Dict[str, Any]) -> Dict[str, Any]: # 工具实现 return {"result": "success"}

工具注册表

ToolRegistry 把工具名映射到实现:

registry = ToolRegistry() tool = registry.get_tool("Grep", system_state) result = tool.execute(params)

系统状态

SystemState 跟踪:

  • 当前工作目录
  • 工具调用计数
  • TODO 列表
  • Shell 会话
  • 环境信息

系统提示

系统提示在每次 LLM 调用前注入:

<system_hint> # System State Current Time: 2025-10-12 15:30:45 Working Directory: /Users/boj/coding-agent OS: Darwin Python: Python 3.11.5 # Tool Call Statistics - Grep: 2 calls - Write: 1 calls # Current TODO List ✅ [1] Search for files (completed) 🔄 [2] Implement feature (in_progress) ⬜ [3] Write tests (pending) </system_hint>

设计原则

1. 纯 Python 实现

原因: 最大化的可移植性与兼容性

  • 在任何装有 Python 的系统上都能运行
  • 无需 Homebrew、apt 或其他包管理器
  • 跨平台行为一致

2. 模块化工具架构

原因: 可维护性与可扩展性

  • 每个工具自包含
  • 易于添加新工具
  • 易于单独测试
  • 职责清晰分离

3. 无命令行依赖

原因: 可靠性与可控性

  • Grep:纯 Python 正则检索
  • Glob:Python 的 pathlib.glob()
  • LS:Python 的 ospathlib
  • 核心功能不使用 subprocess 调用
  • 对行为的完全掌控

4. 用于自我感知的系统提示

原因: 更好的 Agent 行为

  • 防止无限循环(工具调用计数)
  • 保持任务专注(TODO 跟踪)
  • 提供环境上下文
  • 实现自我监控

与第 2 章的对照

技术 状态 实现
标准 OpenAI 工具格式 支持 Anthropic SDK
流式工具调用 支持 实时 JSON delta 解析
并行工具调用 支持 每次响应多个工具
纯 Python 工具 支持 无命令行依赖
无需 rg 的 Grep 支持 纯 Python 正则检索
时间戳 支持 所有消息 / 工具
工具调用计数 支持 3 次以上告警
TODO 列表 支持 TodoWrite 工具
系统状态 支持 工作目录、OS、Python
持久化 Shell 支持 Shell 会话
自动 lint 检测 支持 Write/Edit/MultiEdit 之后

配置

.env 文件:

# 必需 ANTHROPIC_API_KEY=your_key_here # 可选 DEFAULT_MODEL=claude-sonnet-5 MAX_ITERATIONS=50 MAX_TOKENS=8192

添加新工具

  1. tools/ 中创建工具文件:
# tools/my_tool.py from .base import BaseTool class MyTool(BaseTool): @property def name(self) -> str: return "MyTool" def _execute_impl(self, params): # 实现 return {"result": "success"}
  1. tools/__init__.py 中注册:
from .my_tool import MyTool __all__ = [..., 'MyTool']
  1. tool_registry.py 中添加:
self._tools = { ..., "MyTool": MyTool, }
  1. tools.json 中添加定义

故障排查

"No module named 'tools'"

确认你是从项目目录运行的:

cd /Users/boj/ai-agent-book/projects/week5/coding-agent python agent.py

Grep 找不到文件

检查:

  • 路径是否正确
  • 模式是否为合法正则
  • Glob 模式是否匹配到文件
  • 文件是否包含可检索的文本(而非二进制)

Shell 命令失败

确认:

  • /bin/bash 可用
  • 工作目录存在
  • 命令已正确加引号

测试

包含 130+ 测试的完整测试套件,覆盖所有工具特性。

运行测试

# 安装测试依赖 pip install -r requirements.txt # 运行全部测试 pytest # 带覆盖率运行 pytest --cov=tools --cov-report=html # 运行特定工具的测试 pytest tests/test_grep_tool.py pytest tests/test_bash_tool.py # 详细输出 pytest -v

测试覆盖

  • 130+ 测试,分布在 14 个测试文件中
  • 2200+ 行测试代码
  • tools.json 中的所有主要特性均有测试
  • 工具链与系统提示的集成测试

详细测试文档见 tests/README.md。

学习路径

  1. 从示例开始:运行 python main.py(交互式 CLI)
  2. 运行快速入门python quickstart.py
  3. 探索系统提示python example_with_system_hints.py
  4. 研读 Grep 实现:参见 tools/grep_tool.py
  5. 运行测试pytest -v 观察所有特性
  6. 阅读第 2 章:理解理论
  7. 添加自定义工具:扩展系统

参考资料

  • 第 2 章:上下文工程(AI Agent Book)
  • 工具规格:tools.json
  • 系统提示:system-prompt.md
  • Anthropic Claude API:https://docs.anthropic.com/

核心优势

  1. 不依赖外部工具

    • 纯 Python 实现
    • 无需 rg、grep、find 等即可工作
    • 完美适合没有 Homebrew 的 Mac 用户
  2. 模块化架构

    • 每个工具是一个独立文件
    • 易于理解与修改
    • 职责清晰分离
  3. 面向生产

    • 完善的错误处理
    • 自动 lint 检测
    • 用于可靠性的系统提示
    • 提升体验的流式支持
  4. 教学价值

    • 了解工具的内部工作原理
    • 理解纯 Python 文件操作
    • 观摩正则检索实现
    • 学习 Agent 架构模式

许可证

MIT

贡献

这是一个教学实现。欢迎自由改编与扩展!

用纯 Python 打造,追求最大的可移植性与学习价值!


作者与出处
原作者: bojieli
来源:bojieli
许可证:Apache-2.0
整理: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: bojieli 转发
评论区 (0)
U