Agent 工作流拆解:从提示词到工具调用到代码产出到验证的完整工作流
简介
会用工具只是第一步,理解工具"为什么这样做"才是进阶的关键。本文带你逐帧拆解 AI 编程 Agent 的完整工作流,从你输入提示词的那一刻开始,到 Agent 交出最终产出的全过程。
很多开发者使用 AI 编程 Agent 时感到"像是在抽奖"——有时候效果好,有时候差。根本原因是不了解 Agent 的内部工作流,不知道它在每个阶段需要什么、在做什么、为什么犯错。本文将 Agent 的完整工作流拆解为 7 个阶段,每个阶段都有详细的内部逻辑、示例和最佳实践。读完这篇文章,你将能更精准地给 Agent 下指令,更高效地审查 Agent 的产出。
本文目录
- Agent 工作流的 7 个阶段总览
- 阶段 1:提示词解析与意图理解
- 阶段 2:代码库探索与上下文构建
- 阶段 3:任务规划与策略制定
- 阶段 4:代码生成与文件修改
- 阶段 5:测试运行与验证
- 阶段 6:错误分析与自我修正
- 阶段 7:产出交付与变更摘要
- 实战:完整工作流逐帧追踪
- 总结与下篇预告
1. Agent 工作流的 7 个阶段总览
当我们给 Agent 下达一个任务时,它内部会经历以下 7 个阶段:
┌─────────────────────────────────────────────────────────────┐
│ Agent 完整工作流 │
├──────┬──────────┬──────────┬──────────┬─────────┬───────────┤
│ 阶段1 │ 阶段2 │ 阶段3 │ 阶段4 │ 阶段5 │ 阶段6 │
│ 解析 │ 探索 │ 规划 │ 执行 │ 验证 │ 修正 │
└──┬───┴────┬─────┴────┬─────┴────┬─────┴────┬────┴─────┬─────┘
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
意图 上下文 计划 代码 测试 修复
理解 构建 制定 产出 运行 迭代
│
通过?
╱ ╲
是 否
│ │
▼ ▼
┌─────────┐ ┌──────┐
│ 阶段7 │ │阶段6 │
│ 交付 │← │ 修正 │
└─────────┘ └──────┘每个阶段都有明确的输入、处理逻辑和输出。理解这个流程,你就能知道:
- 为什么 Agent 有时候会做错
- 如何给 Agent 更好的指令
- 怎样更高效地审查 Agent 的产出
2. 阶段 1:提示词解析与意图理解
这是 Agent 工作的起点。你的提示词质量,直接决定了后续所有阶段的效果。
2.1 Agent 如何解析你的指令
当你输入:
给 /api/users 接口添加一个按用户名模糊搜索的功能,支持分页Agent 内部会进行以下解析:
# Agent 内部解析结果(概念示意)
parsed_task = {
"target": "/api/users 接口", # 目标定位
"action": "添加功能", # 动作类型
"feature": "用户名模糊搜索 + 分页", # 功能描述
"parameters": { # 推断的参数
"search_param": "username (模糊匹配)",
"page": "page (整数, 默认1)",
"page_size": "page_size (整数, 默认20)"
},
"implicit_requirements": { # 隐含需求推断
"保持向后兼容": True, # 现有调用方不能报错
"遵循现有风格": True, # 与项目其他接口一致
"需要测试": True, # 新功能应有测试覆盖
"需要文档": True, # API 变更应更新文档
}
}2.2 好提示词 vs 差提示词
❌ 差提示词:
"加个搜索"
→ 模糊不清,Agent 需要猜测目标、范围、实现方式
❌ 较差提示词:
"给用户 API 加搜索"
→ 有目标但缺少约束条件
✅ 好提示词:
"给 /api/users GET 接口添加 username 模糊搜索参数,
使用 PostgreSQL 的 ILIKE 操作符,
同时添加分页支持(page, page_size),
保持向后兼容(不传搜索参数时返回全部结果),
参考 /api/products 接口的实现风格"
→ 目标明确、技术选型指定、约束清晰、有参考2.3 提示词工程的 4 个关键要素
| 要素 | 说明 | 示例 |
|---|---|---|
| 目标 | 要做什么 | "给 /api/users 添加搜索" |
| 约束 | 不能做什么/必须怎么做 | "保持向后兼容"、"使用 ILIKE" |
| 参考 | 参考什么风格/模式 | "参考 /api/products 的实现" |
| 验收 | 怎么算完成 | "需要通过现有测试 + 新增 3 个测试用例" |
3. 阶段 2:代码库探索与上下文构建
Agent 不会直接开始写代码。它首先需要"理解"你的项目。
3.1 探索策略
Agent 的探索路径(概念示意):
Step 1: 快速扫描
→ 读取项目根目录结构
→ 识别项目类型 (Python/Node/Go/Rust...)
→ 定位入口文件和配置文件
Step 2: 目标定位
→ 搜索 "/api/users" 相关的路由定义
→ 找到处理该接口的视图/控制器文件
Step 3: 上下文扩展
→ 读取目标文件的完整内容
→ 追踪 imports,了解依赖
→ 查找相关测试文件
→ 读取参考文件(如 /api/products)
Step 4: 依赖分析
→ 检查数据库模型定义
→ 检查序列化器/响应格式
→ 检查中间件/权限逻辑3.2 实际探索过程展示
# Agent 内部工具调用序列(阶段 2)
[TOOL_CALL] grep -r "users" src/api/routes/
[TOOL_RESULT] src/api/routes/user_routes.py:12: @router.get("/users")
[TOOL_CALL] read_file("src/api/routes/user_routes.py")
[TOOL_RESULT] (读取 150 行代码)
[TOOL_CALL] read_file("src/models/user.py")
[TOOL_RESULT] (读取 User 模型定义)
[TOOL_CALL] read_file("src/api/routes/product_routes.py") # 参考
[TOOL_RESULT] (读取参考实现,学习搜索+分页模式)
[TOOL_CALL] grep -r "test.*user" tests/
[TOOL_RESULT] tests/test_user_routes.py
[TOOL_CALL] read_file("tests/test_user_routes.py")
[TOOL_RESULT] (读取现有测试,了解测试风格)3.3 上下文构建的效率优化
Agent 不会把所有文件都塞进上下文窗口(那样太贵也太慢)。它使用以下策略:
上下文优化策略:
1. 按需读取 (Read-on-Demand)
- 只读取与当前任务直接相关的文件
- 需要时再深入读取关联文件
2. 摘要缓存 (Summary Caching)
- 对已读取的文件生成摘要
- 后续需要时先查摘要,再决定是否读全文
3. 分层索引 (Hierarchical Indexing)
- 第1层:文件树 + 文件摘要
- 第2层:关键函数签名 + 类定义
- 第3层:完整代码(按需读取)4. 阶段 3:任务规划与策略制定
在充分理解代码库后,Agent 会制定详细的执行计划。
4.1 规划输出示例
[PLAN] 任务:给 /api/users 添加用户名模糊搜索 + 分页
执行计划(共 6 步):
Step 1: 修改路由定义
文件: src/api/routes/user_routes.py
变更: 添加 query 参数 username, page, page_size
风险: 低
Step 2: 修改数据库查询
文件: src/services/user_service.py
变更: 添加 ILIKE 搜索条件和 LIMIT/OFFSET
风险: 中(可能影响查询性能)
Step 3: 修改响应格式
文件: src/schemas/user_schema.py
变更: 添加分页响应包装 (total, items, page, page_size)
风险: 中(可能影响现有调用方)
Step 4: 编写测试
文件: tests/test_user_routes.py
变更: 添加 3 个新测试用例
风险: 低
Step 5: 运行测试
命令: pytest tests/test_user_routes.py -v
预期: 所有测试通过
Step 6: 更新 API 文档
文件: docs/api/users.md
变更: 添加新参数说明
风险: 低
是否需要我按计划执行?[Y/N/E(编辑)]4.2 为什么规划很重要
很多 Agent 产出的质量问题,根源在于跳过了规划阶段直接写代码。好的规划:
- 降低出错率:先想清楚再动手
- 提高一致性:确保所有变更协调一致
- 便于审查:人类可以在执行前审查计划
- 支持回滚:出了问题知道改了什么
4.3 不同类型任务的规划模式
┌─────────────────────────────────────────────────┐
│ 添加新功能 │
│ 理解现有 → 定位插入点 → 编写代码 → 添加测试 │
├─────────────────────────────────────────────────┤
│ 修复 Bug │
│ 复现问题 → 定位根因 → 修复代码 → 添加回归测试 │
├─────────────────────────────────────────────────┤
│ 代码重构 │
│ 分析依赖 → 设计新结构 → 迁移代码 → 验证一致性 │
├─────────────────────────────────────────────────┤
│ 编写测试 │
│ 理解被测代码 → 识别边界条件 → 编写用例 → 验证 │
└─────────────────────────────────────────────────┘5. 阶段 4:代码生成与文件修改
这是 Agent 最核心的执行阶段。
5.1 文件编辑的两种方式
方式 1: 精确行级编辑(Claude Code、Hermes Agent)
────────────────────────────────────────
[TOOL: file_editor]
file: "src/api/routes/user_routes.py"
start_line: 15
end_line: 18
new_content: |
username: Optional[str] = Query(None, description="用户名搜索"),
page: int = Query(1, ge=1, description="页码"),
page_size: int = Query(20, ge=1, le=100, description="每页数量"),
→ 只替换指定行,其余内容不变
→ 更安全,减少意外修改
方式 2: 文件级替换(部分开源工具)
────────────────────────────────────────
[TOOL: write_file]
file: "src/api/routes/user_routes.py"
content: |
# 整个文件的完整内容...
# ...(200 行代码)
→ 需要输出整个文件
→ 更容易引入意外变更
→ 消耗更多 token5.2 代码生成的质量保障
Agent 在生成代码时会做以下检查:
# Agent 内部质量检查流程(概念示意)
def generate_code(task, context):
code = llm.generate(task, context)
# 1. 语法检查
if not syntax_check(code, language="python"):
return generate_code(task, context, feedback="语法错误")
# 2. 风格检查(参考现有代码)
style_diff = compare_style(code, context.sample_code)
if style_diff > threshold:
return generate_code(task, context, feedback="风格不一致")
# 3. 安全检查
if security_scan(code):
return generate_code(task, context, feedback="安全风险")
return code5.3 多文件修改的协调
复杂任务通常需要修改多个文件,Agent 需要确保所有修改协调一致:
多文件修改协调示例:
修改 1: src/api/routes/user_routes.py ← 添加路由参数
修改 2: src/services/user_service.py ← 修改查询逻辑
修改 3: src/schemas/user_schema.py ← 修改响应格式
修改 4: tests/test_user_routes.py ← 添加测试
修改 5: docs/api/users.md ← 更新文档
Agent 的协调逻辑:
1. 确保修改 2 的查询参数与修改 1 的路由参数一致
2. 确保修改 3 的响应格式与修改 2 的返回数据一致
3. 确保修改 4 的测试覆盖了修改 1-3 的所有变更
4. 确保修改 5 的文档描述与实际实现一致6. 阶段 5:测试运行与验证
代码写完后,Agent 不会直接说"完成了"。它会运行测试来验证。
6.1 测试执行流程
# Agent 的测试执行序列
[TOOL_CALL] pytest tests/test_user_routes.py -v --tb=short
[TOOL_RESULT]
tests/test_user_routes.py::test_get_users PASSED ✓
tests/test_user_routes.py::test_get_user_by_id PASSED ✓
tests/test_user_routes.py::test_search_users PASSED ✓
tests/test_user_routes.py::test_pagination PASSED ✓
tests/test_user_routes.py::test_search_with_pagination PASSED ✓
========================================
5 passed in 2.34s
========================================
[AGENT] ✅ 所有测试通过,任务完成。6.2 测试策略的层级
Agent 的测试验证层级:
Level 1: 单元测试
→ 验证新增功能的逻辑正确性
→ pytest tests/test_user_routes.py::test_search_users
Level 2: 集成测试
→ 验证新代码与现有系统的集成
→ pytest tests/test_integration.py
Level 3: 回归测试
→ 确保新代码没有破坏现有功能
→ pytest tests/ (全量运行)
Level 4: 类型检查
→ 验证类型注解的一致性
→ mypy src/
Level 5: Lint 检查
→ 验证代码风格
→ ruff check src/6.3 真实 Agent 的测试输出
┌─────────────────────────────────────────────────┐
│ 🧪 测试运行结果 │
├─────────────────────────────────────────────────┤
│ │
│ tests/test_user_routes.py │
│ ✓ test_get_users 0.45s │
│ ✓ test_get_user_by_id 0.32s │
│ ✓ test_search_users_by_name 0.28s │
│ ✓ test_search_users_no_match 0.15s │
│ ✓ test_pagination_default 0.22s │
│ ✓ test_pagination_custom_page 0.19s │
│ ✓ test_search_with_pagination 0.31s │
│ │
│ 7 passed, 0 failed in 1.92s │
│ │
│ 📊 代码覆盖率: 94.2% │
│ │
│ ✅ 所有测试通过! │
│ │
└─────────────────────────────────────────────────┘7. 阶段 6:错误分析与自我修正
这是 Agent 最强大的能力——当测试失败时,它不会问你"怎么办",而是自己分析并修复。
7.1 错误分析流程
假设测试失败了:
[TOOL_RESULT]
======================================== FAILURES ========================================
_____________________________ test_search_users_by_name _________________________________
def test_search_users_by_name():
response = client.get("/api/users?username=test")
> assert response.status_code == 200
E assert 422 == 200
tests/test_user_routes.py:45: AssertionError
================================= short test summary info =================================
FAILED tests/test_user_routes.py::test_search_users_by_name - assert 422 == 200
============================== 1 failed, 6 passed in 1.89s ================================
[AGENT] 分析中...
Agent 推理链:
1. 状态码 422 = Unprocessable Entity = 请求参数验证失败
2. 我刚刚添加了 username, page, page_size 参数
3. 测试请求只传了 username,没有传 page 和 page_size
4. 检查代码 → page 参数定义为 Query(ge=1),没有默认值
5. → 问题找到了:分页参数缺少默认值
[SELF_FIX] 正在修复...
[TOOL_CALL] file_editor("src/api/routes/user_routes.py",
line=17,
content=" page: int = Query(1, ge=1, description=\"页码\"),")
[TOOL_RESULT] 文件修改成功
[RE-TEST] pytest tests/test_user_routes.py -v
[TOOL_RESULT] 7 passed, 0 failed ✓7.2 自我修正的迭代上限
Agent 不会无限循环修正。它通常有以下约束:
修正迭代约束:
├── 最大迭代次数: 5-10 次(取决于工具配置)
├── 终止条件:
│ ├── 测试全部通过 → 正常完成
│ ├── 达到最大迭代次数 → 报告失败
│ ├── 遇到无法自动解决的问题 → 请求人工介入
│ └── 检测到可能引入更大问题 → 停止并报告
└── 安全机制:
├── 不修改超出任务范围的文件
├── 不执行破坏性命令(rm -rf 等)
└── 保留修改前的文件快照(用于回滚)7.3 常见错误类型与 Agent 的修复策略
| 错误类型 | 示例 | Agent 修复策略 |
|---|---|---|
| 语法错误 | SyntaxError: invalid syntax |
重新生成代码块,检查括号/缩进 |
| 类型错误 | TypeError: expected str, got int |
检查变量类型,添加类型转换 |
| 导入错误 | ModuleNotFoundError: No module |
检查 import 路径,添加缺失依赖 |
| 断言失败 | AssertionError: 422 != 200 |
分析状态码含义,检查请求参数 |
| 空指针 | AttributeError: 'NoneType' |
添加空值检查/防御性编程 |
| 测试遗漏 | 新代码无测试覆盖 | 自动补充测试用例 |
8. 阶段 7:产出交付与变更摘要
当所有测试通过后,Agent 会生成变更摘要,交付最终结果。
8.1 变更摘要示例
┌─────────────────────────────────────────────────┐
│ ✅ 任务完成:给 /api/users 添加搜索 + 分页功能 │
├─────────────────────────────────────────────────┤
│ │
│ 📝 变更摘要 │
│ │
│ 修改的文件 (5): │
│ M src/api/routes/user_routes.py │
│ M src/services/user_service.py │
│ M src/schemas/user_schema.py │
│ M tests/test_user_routes.py │
│ M docs/api/users.md │
│ │
│ 新增的代码行: +86 │
│ 删除的代码行: -12 │
│ │
│ 📊 测试结果 │
│ 7 passed, 0 failed │
│ 覆盖率: 94.2% │
│ │
│ 🔄 修正迭代: 1 次 │
│ (修复了分页参数缺少默认值的问题) │
│ │
│ 💡 建议 │
│ - 考虑为搜索添加索引以提升性能 │
│ - 建议对 page_size 添加上限限制 │
│ │
└─────────────────────────────────────────────────┘8.2 Git 集成
# Agent 生成的 Git diff
$ git diff
diff --git a/src/api/routes/user_routes.py b/src/api/routes/user_routes.py
--- a/src/api/routes/user_routes.py
+++ b/src/api/routes/user_routes.py
@@ -12,7 +12,10 @@ from fastapi import APIRouter, Depends
@router.get("/users")
-async def get_users(db: Session = Depends(get_db)):
+async def get_users(
+ username: Optional[str] = Query(None),
+ page: int = Query(1, ge=1),
+ page_size: int = Query(20, ge=1, le=100),
+ db: Session = Depends(get_db),
+):
users = get_all_users(db)
- return users
+ return paginate(users, page, page_size)
# Agent 可以自动提交
[TOOL_CALL] git add -A
[TOOL_CALL] git commit -m "feat: add username search and pagination to /api/users
- Add ILIKE search on username field
- Add page/page_size query parameters with defaults
- Update response format to include pagination metadata
- Add 3 new test cases for search and pagination
- Update API documentation"9. 实战:完整工作流逐帧追踪
让我们用一个完整任务,把 7 个阶段串联起来:
任务: "给 Flask 项目添加一个 /api/health 健康检查端点"
═══════════════════════════════════════════════════
阶段 1: 提示词解析
═══════════════════════════════════════════════════
Agent: "收到。添加健康检查端点,我需要:
1. 定位 Flask 应用入口
2. 添加 /api/health 路由
3. 返回服务状态信息
4. 添加测试"
═══════════════════════════════════════════════════
阶段 2: 代码库探索
═══════════════════════════════════════════════════
[TOOL] grep -r "Flask\|app = " src/
[TOOL] read_file("src/app.py") # 找到 Flask 应用
[TOOL] read_file("src/api/__init__.py") # 找到 Blueprint
[TOOL] read_file("tests/conftest.py") # 找到测试配置
═══════════════════════════════════════════════════
阶段 3: 任务规划
═══════════════════════════════════════════════════
Agent: "计划如下:
1. 在 src/api/health.py 创建健康检查路由
2. 在 src/api/__init__.py 注册 Blueprint
3. 添加测试 tests/test_health.py
4. 运行测试验证"
═══════════════════════════════════════════════════
阶段 4: 代码生成
═══════════════════════════════════════════════════
[TOOL] write_file("src/api/health.py")
[TOOL] edit_file("src/api/__init__.py") # 注册 Blueprint
═══════════════════════════════════════════════════
阶段 5: 测试运行
═══════════════════════════════════════════════════
[TOOL] pytest tests/test_health.py -v
[RESULT]
✓ test_health_check
✓ test_health_check_content_type
✓ test_health_check_with_db
3 passed ✓
═══════════════════════════════════════════════════
阶段 6: 无需修正(一次通过)
═══════════════════════════════════════════════════
(跳过)
═══════════════════════════════════════════════════
阶段 7: 交付
═══════════════════════════════════════════════════
Agent: "✅ 完成!变更摘要:
+ src/api/health.py (新建,23行)
M src/api/__init__.py (+2行,注册 Blueprint)
+ tests/test_health.py (新建,45行)
3 个测试全部通过。
访问 http://localhost:5000/api/health 即可使用。"10. 总结
本文深入拆解了 AI 编程 Agent 的完整工作流:
- 提示词解析:Agent 会解析你的指令,提取目标、约束、隐含需求。提示词质量决定一切。
- 代码库探索:Agent 通过文件扫描、语义搜索、依赖分析构建上下文,不是盲目操作。
- 任务规划:好的 Agent 会先制定计划再执行,计划本身也是审查的一部分。
- 代码生成:精确编辑 vs 文件替换,多文件协调是难点。
- 测试验证:单元测试 → 集成测试 → 回归测试 → 类型检查 → Lint,层层验证。
- 自我修正:分析错误 → 定位根因 → 自动修复 → 重新测试,这是 Agent 最核心的能力。
- 产出交付:变更摘要 + Git diff + 建议,方便人类审查。
核心洞察:Agent 不是魔法,它是一个有明确工作流的"自动化编程引擎"。理解它的工作流,你就能更好地使用它、审查它、改进它。