阅读指南
属性 说明 预计阅读 15-20 分钟 前置文档 docs/swe-agent/04-swe-agent-agent-loop.md、docs/swe-agent/11-swe-agent-prompt-organization.md文档结构 结论 → 架构 → 组件分析 → 数据流 → 代码实现 → 对比 代码呈现 关键代码直接展示,完整代码可折叠查看
SWE-agent 没有实现专门的 "plan and execute" 模式,而是采用统一的 thought-action 循环架构,将规划和执行集成在单个步骤中。
SWE-agent 的核心取舍:简化架构,隐式规划(对比 Codex 的显式 Plan/Execute 模式切换、Gemini CLI 的 ApprovalMode 状态机)
| 维度 | 关键决策 | 代码位置 |
|---|---|---|
| 核心机制 | Thought-Action 统一循环,无显式阶段分离 | sweagent/agent/agents.py:step() |
| 规划方式 | 隐式规划:每 step 内部通过 thought 完成 | sweagent/tools/parsing.py:ThoughtActionParser |
| 模板引导 | system_template + instance_template 提供程序性指导 | sweagent/agent/agents.py:TemplateConfig |
| 错误处理 | FormatError 时通过错误模板反馈重试 | sweagent/agent/agents.py:1153 |
Plan-and-Execute 模式试图解决:
- 复杂任务需要预先规划
- 执行前需要用户确认计划
- 规划阶段需要限制工具使用
SWE-agent 的设计选择:
- 软件工程任务往往需要边探索边调整
- 预先制定完整计划困难且容易过时
- 每步都重新规划更灵活
传统 Plan-and-Execute 的问题:
→ Plan 阶段:制定完整计划(禁止执行工具)
→ 用户确认:等待用户审批
→ Execute 阶段:按计划执行
问题:软件工程任务难以预先规划,环境变化快
SWE-agent 的 Thought-Action 模式:
→ Step 1: Thought(分析) → Action(执行) → Observation(观察)
→ Step 2: Thought(基于新信息重新分析) → Action → Observation
→ Step N: 持续迭代直到完成
优势:每步都可根据最新观察调整策略
| 挑战 | Plan-and-Execute | Thought-Action |
|---|---|---|
| 任务适应性 | 适合预定义流程 | 适合探索性任务 |
| 用户交互 | 需要确认环节 | 自主执行 |
| 架构复杂度 | 需要模式切换 | 简单统一 |
| 灵活性 | 计划变更成本高 | 每步可调整 |
┌─────────────────────────────────────────────────────────────┐
│ CLI Entry / Batch Runner │
│ sweagent/run/run_single.py │
└───────────────────────┬─────────────────────────────────────┘
│ 调用
▼
┌─────────────────────────────────────────────────────────────┐
│ ▓▓▓ Agent Loop (Thought-Action) ▓▓▓ │
│ sweagent/agent/agents.py │
│ - run() : 主循环入口 │
│ - step() : 单步 thought + action + observation │
│ - forward() : LLM 查询 │
│ - parse_response(): 提取 thought/action │
└───────────────────────┬─────────────────────────────────────┘
│ 依赖/调用
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ LLM API │ │ Tool System │ │ Template │
│ 模型调用 │ │ 工具执行 │ │ 模板渲染 │
└──────────────┘ └──────────────┘ └──────────────┘
| 组件 | 职责 | 代码位置 |
|---|---|---|
Agent.run() |
主循环入口,驱动多轮 step | sweagent/agent/agents.py:1265 |
Agent.step() |
单步执行:查询 → 解析 → 执行 → 记录 | sweagent/agent/agents.py:1037 |
forward() |
调用 LLM,处理上下文和响应 | sweagent/agent/agents.py:1018 |
ThoughtActionParser |
解析模型响应,提取 thought 和 action | sweagent/tools/parsing.py |
TemplateConfig |
配置 system/instance/next_step 模板 | sweagent/agent/agents.py:60 |
sequenceDiagram
autonumber
participant A as Agent Loop
participant B as step()
participant C as forward()
participant D as ThoughtActionParser
participant E as Tool System
A->>B: 1. 调用 step()
B->>C: 2. 查询 LLM
C-->>B: 3. 返回 response
B->>D: 4. 解析 thought + action
D-->>B: 5. 返回 (thought, action)
B->>E: 6. 执行 action
E-->>B: 7. 返回 observation
B->>B: 8. 记录 trajectory
B-->>A: 9. 返回 StepOutput
关键交互说明:
| 步骤 | 交互内容 | 设计意图 |
|---|---|---|
| 1 | Agent Loop 调用 step() | 统一入口,简化控制流 |
| 2-3 | 查询 LLM 获取响应 | 获取模型的 thought 和 action |
| 4-5 | 解析响应提取结构 | 将自由文本转为结构化数据 |
| 6-7 | 执行工具获取观察 | 实际影响环境,获取反馈 |
| 8 | 记录完整轨迹 | 支持断点续传和结果分析 |
每个步骤包含完整的 thought-action-observation 周期,规划发生在 thought 阶段,执行发生在 action 阶段,两者在同一个 step 内完成。
stateDiagram-v2
[*] --> Querying: 开始 step
Querying --> Parsing: 收到 LLM 响应
Parsing --> Executing: 提取 action
Parsing --> FormatError: 解析失败
FormatError --> Querying: 错误反馈 + 重试
Executing --> Observing: action 完成
Observing --> Recording: 获得 observation
Recording --> [*]: 返回 StepOutput
note right of Querying
forward() 调用 LLM
包含完整上下文
end note
note right of Parsing
ThoughtActionParser
提取 thought 和 action
end note
状态说明:
| 状态 | 说明 | 进入条件 | 退出条件 |
|---|---|---|---|
| Querying | 查询 LLM | step() 开始 | 收到响应或出错 |
| Parsing | 解析响应 | 收到 LLM 响应 | 成功提取或格式错误 |
| Executing | 执行 action | 成功解析 action | action 完成 |
| Observing | 获取观察 | action 执行完成 | 获得 observation |
| Recording | 记录轨迹 | 获得 observation | 保存完成 |
| FormatError | 格式错误 | 解析失败 | 重试或终止 |
┌─────────────────────────────────────────────────────────────┐
│ Thought-Action 循环内部数据流 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 输入层 │
│ ├── History (对话历史) │
│ ├── System Template (系统身份定义) │
│ ├── Instance Template (问题描述) │
│ └── Next Step Template (下一步指导) │
│ │ │
│ ▼ │
│ 处理层 │
│ ├── forward(): 构造 prompt → 调用 LLM │
│ ├── parse_response(): 提取 thought + action │
│ └── execute_action(): 执行工具调用 │
│ │ │
│ ▼ │
│ 输出层 │
│ ├── StepOutput (thought, action, observation) │
│ └── Trajectory (完整执行历史) │
│ │
└─────────────────────────────────────────────────────────────┘
解析模型响应,提取 thought(自由文本)和 action(代码块格式)。
| 接口 | 输入 | 输出 | 说明 | 代码位置 |
|---|---|---|---|---|
parse() |
模型响应文本 | (thought, action) |
主解析方法 | sweagent/tools/parsing.py |
extract_action() |
响应文本 | action 字符串 | 提取代码块 | sweagent/tools/parsing.py |
extract_thought() |
响应文本 | thought 字符串 | 提取自由文本 | sweagent/tools/parsing.py |
sequenceDiagram
participant A as Agent Loop
participant B as step()
participant C as LLM
participant D as ThoughtActionParser
participant E as Environment
A->>B: 调用 step()
B->>C: 查询模型 (forward)
C-->>B: 返回 response
B->>D: parse_response(response)
D-->>B: 返回 (thought, action)
B->>E: 执行 action
E-->>B: 返回 observation
B->>B: 记录 trajectory
B-->>A: 返回 StepOutput
数据变换详情:
| 阶段 | 输入 | 处理 | 输出 | 代码位置 |
|---|---|---|---|---|
| 查询 | History + Templates | 构造 prompt | LLM 请求 | agents.py:1018 |
| 响应 | LLM 响应 | 接收响应文本 | raw_response | agents.py:1040 |
| 解析 | raw_response | 提取 thought/action | (thought, action) | agents.py:1045 |
| 执行 | action | 调用工具 | observation | agents.py:1050 |
| 记录 | step 数据 | 序列化 JSON | trajectory 文件 | agents.py:779 |
flowchart LR
subgraph Input["输入阶段"]
I1[用户问题] --> I2[模板注入]
I2 --> I3[完整 Prompt]
end
subgraph Process["处理阶段"]
P1[Query Model] --> P2[Parse Response]
P2 --> P3[Extract Thought]
P2 --> P4[Extract Action]
P3 --> P5[隐式规划]
P4 --> P6[执行 Action]
end
subgraph Output["输出阶段"]
O1[StepOutput]
O2[Trajectory 记录]
end
I3 --> P1
P5 --> O1
P6 --> O1
O1 --> O2
style Process fill:#e1f5e1,stroke:#333
flowchart TD
A[开始 step] --> B{解析成功?}
B -->|是| C[执行 action]
B -->|否| D[FormatError]
D --> E{重试次数 < 上限?}
E -->|是| F[构造错误反馈]
F --> G[重新查询 LLM]
G --> B
E -->|否| H[终止 Agent]
C --> I{执行成功?}
I -->|是| J[记录并返回]
I -->|否| K[返回错误观察]
J --> L[结束]
K --> L
H --> L
# sweagent/agent/agents.py:60-75
class TemplateConfig(BaseModel):
"""模板配置:定义 Agent 的行为模式"""
system_template: str = ""
"""系统身份定义:告诉模型它是谁、能做什么"""
instance_template: str = ""
"""问题实例描述:当前任务的具体信息"""
next_step_template: str = "Observation: {{observation}}"
"""下一步指导:如何构造下一步的提示"""
strategy_template: str | None = None
"""战略规划模板(可选):额外的规划指导"""字段说明:
| 字段 | 类型 | 用途 |
|---|---|---|
system_template |
str |
系统身份定义,包含角色和能力说明 |
instance_template |
str |
问题实例描述,包含具体任务信息 |
next_step_template |
str |
下一步指导,控制 thought-action 格式 |
strategy_template |
`str | None` |
关键代码(核心逻辑):
# sweagent/agent/agents.py:1037-1070
def step(self) -> StepOutput:
"""Single step: query model, extract thought/action, execute."""
# 1. 查询 LLM,带错误处理和重试
response = self.forward_with_handling()
# 2. 解析响应,提取 thought 和 action
thought, action = self.parse_response(response)
# 3. 执行 action,获取 observation
observation = self.execute_action(action)
# 4. 记录到 trajectory
self.trajectory.add_step(thought, action, observation)
return StepOutput(
thought=thought,
action=action,
observation=observation
)
def run(self, env, problem_statement, output_dir) -> AgentRunResult:
"""Run the agent: thought-action loop until done."""
self.setup(env=env, problem_statement=problem_statement, output_dir=output_dir)
step_output = StepOutput()
while not step_output.done:
step_output = self.step() # 单步 thought+action+observation
self.save_trajectory() # 每步保存设计意图:
- 统一循环:无阶段分离,每个迭代执行完整周期,简化架构
- 隐式规划:规划发生在 thought 阶段,通过模板引导模型自我讨论
- 每步持久化:支持断点续传和结果分析
查看完整实现
# sweagent/agent/agents.py:1037-1100
@traced
async def step(self) -> StepOutput:
"""Single step of the agent: query model, parse, execute."""
self.logger.info("STEP %d", self._step_count)
# 查询模型(带错误处理)
response = await self.forward_with_handling()
# 解析 thought 和 action
try:
thought, action = self.parse_response(response)
except FormatError as e:
# 格式错误时,构造错误反馈并重试
self._handle_format_error(e)
raise
# 执行 action
observation = await self.execute_action(action)
# 组装输出
step_output = StepOutput(
thought=thought,
action=action,
observation=observation,
done=self._check_done(action, observation)
)
# 更新状态
self._step_count += 1
self._add_step_to_trajectory(step_output)
return step_outputAgent.run() [sweagent/agent/agents.py:1265]
-> step() [sweagent/agent/agents.py:1037]
-> forward_with_handling() [sweagent/agent/agents.py:1062]
-> forward() [sweagent/agent/agents.py:1018]
- 构造 prompt
- 调用 LLM
-> parse_response() [sweagent/agent/agents.py:1045]
-> ThoughtActionParser() [sweagent/tools/parsing.py]
- 提取 thought
- 提取 action
-> execute_action() [sweagent/agent/agents.py:1050]
- 执行工具
- 返回 observation
-> save_trajectory() [sweagent/agent/agents.py:779]
- 持久化到磁盘
| 维度 | SWE-agent 的选择 | 替代方案 | 取舍分析 |
|---|---|---|---|
| 架构模式 | Thought-Action 统一 | Plan-and-Execute 分离 | 简单灵活,适合探索;缺乏系统性规划 |
| 规划时机 | 每步隐式规划 | 预规划阶段 | 适应新信息,但可能重复思考 |
| 用户确认 | 无(自主执行) | 有(ApprovalMode) | 适合自动化,但需更多监督 |
| 工具权限 | 无限制 | Plan 阶段限制 | 灵活但需模型自律 |
| 错误恢复 | forward_with_handling 重试 | 阶段级回滚 | 实现简单,恢复粒度粗 |
核心问题:软件工程任务是否需要显式的 Plan-and-Execute?
SWE-agent 的解决方案:
- 代码依据:
sweagent/agent/agents.py:step() - 设计意图:简化架构,专注探索性任务
- 带来的好处:
- 架构简单,易于实现和维护
- 每步都可调整策略,适应环境变化
- 适合边探索边调整的软件工程任务
- 无需复杂的模式切换逻辑
- 付出的代价:
- 缺乏系统性规划,可能遗漏关键步骤
- 无用户确认环节,不适合敏感操作
- 依赖模型自律,可能产生不当操作
gitGraph
commit id: "基础 Agent 循环"
branch "SWE-agent"
checkout "SWE-agent"
commit id: "Thought-Action 统一"
checkout main
branch "Codex"
checkout "Codex"
commit id: "Plan/Execute 分离"
checkout main
branch "Gemini CLI"
checkout "Gemini CLI"
commit id: "ApprovalMode 状态机"
checkout main
branch "Kimi CLI"
checkout "Kimi CLI"
commit id: "Checkpoint + 子任务"
| 项目 | 核心差异 | 适用场景 |
|---|---|---|
| SWE-agent | Thought-Action 统一循环,隐式规划 | Bug 修复、探索性重构、自动化评测 |
| Codex | 显式 Plan/Execute 模式切换 | 需求明确的大型功能开发 |
| Gemini CLI | ApprovalMode 状态机,用户确认 | 需要用户审批的敏感操作 |
| Kimi CLI | Checkpoint 支持完整状态回滚 | 交互式对话开发 |
| OpenCode | resetTimeoutOnProgress 长任务支持 | 长时间运行的复杂任务 |
| 终止原因 | 触发条件 | 代码位置 |
|---|---|---|
| 任务完成 | step_output.done = True | sweagent/agent/agents.py:1284 |
| 重试耗尽 | n_format_fails >= max_requeries | sweagent/agent/agents.py:1211 |
| 上下文溢出 | ContextWindowExceededError | sweagent/agent/agents.py:1176 |
| 最大步数 | step_count >= max_steps | Agent 配置 |
| 错误类型 | 处理策略 | 代码位置 |
|---|---|---|
| FormatError | 模板反馈 + 重试(最多 3 次) | sweagent/agent/agents.py:1153 |
| 解析失败 | 错误模板提示模型修正格式 | sweagent/tools/parsing.py |
| 工具执行失败 | 返回错误 observation 给 LLM | sweagent/agent/agents.py:1050 |
| LLM API 错误 | 指数退避重试 | sweagent/agent/models.py |
| 功能 | 文件 | 行号 | 说明 |
|---|---|---|---|
| Agent Loop 入口 | sweagent/agent/agents.py |
1265 | run() 主循环 |
| Step 实现 | sweagent/agent/agents.py |
1037 | step() thought-action |
| 模板配置 | sweagent/agent/agents.py |
60 | TemplateConfig 类 |
| 响应解析 | sweagent/tools/parsing.py |
- | ThoughtActionParser |
| 错误处理 | sweagent/agent/agents.py |
1062 | forward_with_handling |
| Trajectory 保存 | sweagent/agent/agents.py |
779 | save_trajectory |
- 前置知识:
docs/swe-agent/04-swe-agent-agent-loop.md(Agent 循环详细分析) - 相关机制:
docs/swe-agent/11-swe-agent-prompt-organization.md(模板系统) - 对比分析:
docs/codex/04-codex-agent-loop.md(Codex 的 Plan-and-Execute 实现) - 对比分析:
docs/gemini-cli/04-gemini-cli-agent-loop.md(Gemini CLI 的 ApprovalMode)
✅ Verified: 基于 sweagent/agent/agents.py、sweagent/tools/parsing.py 等源码分析 基于版本:SWE-agent (baseline 2026-02-08) | 最后更新:2026-03-03