一个用于教学的 TUI Coding Agent 应用,配套博客系列 古明地觉谈 Agent 应用 - 实战篇。
不依赖任何第三方 Agent 框架,仅基于 OpenAI SDK 和少量工具库从零实现,帮助读者理解 Coding Agent 的核心原理。
- Python >= 3.11
- uv 包管理器
git clone https://github.com/your-username/ToyCoder.git
cd ToyCoder
uv sync编辑 config.yaml,填入你的 API Key:
providers:
openai:
api_keys:
- "sk-your-api-key-here"
base_url: "https://api.openai.com/v1"
models:
default: "gpt-4o"
default_provider: "openai"支持任何兼容 OpenAI API 的服务商(DeepSeek、Moonshot 等),只需修改 base_url 和 models。
uv run toycoder或指定配置文件:
uv run toycoder -c /path/to/config.yaml启动后直接输入需求即可,ToyCoder 会自动调用工具完成任务。
| 命令 | 说明 |
|---|---|
/help |
显示帮助信息 |
/new |
新建会话 |
/sessions |
列出所有会话 |
/switch <id> |
切换到指定会话 |
/tools |
列出已注册的工具及状态 |
/tool enable <name> |
启用指定工具 |
/tool disable <name> |
禁用指定工具 |
/model |
显示当前模型信息 |
/quit |
退出程序 |
| 工具 | 权限 | 说明 |
|---|---|---|
read_file |
SAFE | 读取文件内容 |
list_directory |
SAFE | 列出目录内容 |
glob_search |
SAFE | 按模式搜索文件 |
grep_search |
SAFE | 搜索文件内容 |
ask_user |
SAFE | 向用户提问并获取回答 |
write_file |
SENSITIVE | 写入文件(需确认) |
edit_file |
SENSITIVE | 编辑文件(需确认) |
run_command |
DANGEROUS | 执行 Shell 命令(默认禁用) |
planner |
SAFE | 调用 Plan Agent 分解任务 |
- SAFE — 默认启用,自动执行,无需用户干预
- SENSITIVE — 默认启用,每次调用需用户确认;可选择"始终允许"跳过后续确认(会话级)
- DANGEROUS — 默认禁用,需通过
/tool enable <name>手动启用
ToyCoder/
├── config.yaml # 运行时配置
├── pyproject.toml # 项目元数据与依赖
├── data/sessions/ # 会话持久化目录
└── toycoder/
├── __main__.py # CLI 入口
├── app.py # 应用主类,组装各模块
├── config.py # 配置加载与校验
├── agent/
│ ├── react.py # ReAct 循环(同步 + 流式)
│ ├── sub_agent.py # SubAgent 基类
│ └── sub_agent_tool.py # SubAgent → Tool 适配器
├── client/
│ ├── base.py # BaseClient 抽象 + 数据类
│ └── openai_client.py # OpenAI 兼容客户端(多 Key 轮换、重试)
├── command/
│ ├── base.py # Command 数据类 + CommandRegistry
│ └── builtin.py # 内置斜杠命令注册
├── prompt/
│ ├── manager.py # PromptManager(YAML 加载 + 变量渲染)
│ └── templates/
│ └── agents.yaml # Agent 角色 prompt 模板
├── session/
│ └── manager.py # 会话管理 + 上下文压缩 + 持久化
├── tool/
│ ├── permission.py # 三级权限枚举
│ ├── base.py # Tool 基类(Pydantic 自动 schema)
│ ├── manager.py # ToolManager(注册、分发、权限控制)
│ ├── mcp_tool.py # MCP Server 工具适配器
│ └── builtin/
│ ├── file_ops.py # 文件操作工具
│ ├── search.py # 搜索工具
│ ├── shell.py # Shell 命令工具
│ └── question.py # 用户交互工具
└── ui/
└── display.py # Rich TUI 渲染
graph TD
Input[用户输入]
Input --> IsCommand{以 / 开头?}
IsCommand -- 是 --> CR[CommandRegistry.dispatch]
CR --> Handler[对应命令处理函数]
IsCommand -- 否 --> TA[ToyCoderApp.chat]
TA --> CM[上下文管理<br/>截断 / LLM 压缩]
CM --> RL((run_react 循环))
subgraph ReactLoop [run_react 流程]
RL --> LLM[LLM 推理]
LLM --> Decision{回复类型}
Decision -- 文本 --> End[结束回复]
Decision -- Tool Calls --> TM[ToolManager.dispatch]
TM --> Level{安全级别}
Level -- SAFE --> Direct[直接执行]
Level -- SENSITIVE --> Confirm[confirm_callback]
Level -- DANGEROUS --> Enable[需要先 enable]
Enable --> Confirm
Direct --> Result[工具结果]
Confirm --> Result
Result --> RL
end