🔧
架构解析
ChatEngine vs EnhancedChatEngine
双引擎架构解析
CmdCode 拥有两套对话引擎,分别对应普通工具循环和 PAVR 计划执行模式。它们通过 chat-factory.ts 的全局开关来决定谁才是当前会话的主角。
🤖 两个引擎的区别
| 对比项 |
ChatEngine |
EnhancedChatEngine |
| 循环模式 |
普通工具循环 |
PAVR 计划层 |
| 激活条件 |
/pavr 关闭时 |
/pavr 开启时 |
| 执行流程 |
user → model → tool → model → tool → … → output |
user → Plan → Act → Verify → Respond |
| 工具调用方式 |
模型自主决定,立即执行,无确认 |
先输出 JSON 计划,需用户确认后才执行 |
| 安全性 |
⚡ 高效但无中间审核 |
✅ 计划需确认,更安全可控 |
| 源码文件 |
src/chat.ts |
src/chat-enhanced.ts |
ChatEngine — 普通工具循环
这是 CmdCode 的基础对话引擎,采用最直接的工具调用循环:用户发送消息后,模型直接调用工具,边调用边执行,执行结果立即送回模型继续处理,如此循环,直到生成最终回复。
👤 用户
→
🤖 模型
→
🔧 tool_call
→
🤖 模型
→
🔧 tool_call
→
…
→
✅ output
上下文截断优化
该引擎使用消息数量(maxHistoryMessages=100)和 token 上限(~110K)双重截断策略。当工具调用结果过大时,自动丢弃最旧的工具消息,防止上下文撑爆。
maxTurns 限制
该引擎最多执行 80 轮工具调用(曾从 40 提升至 80,以支持 SWE-bench 等复杂任务)。达到上限后强制停止并输出执行摘要。
EnhancedChatEngine — PAVR 计划层
EnhancedChatEngine 是在 ChatEngine 基础上叠加了 PAVR (Plan-Act-Verify-Respond) 计划层。模型不再边调用边执行,而是先输出 JSON 格式的执行计划,用户确认后才真正执行。
👤 用户
→
📋 Plan: JSON 计划
→
✅ 用户确认
→
🔧 Act: 执行工具
→
🔍 Verify: 验证结果
→
💬 Respond: 回复用户
PAVR 的优势
- 计划公开可见:用户可以审核模型即将执行的操作
- 提前纠错:在执行前发现错误的操作步骤
- token 感知截断:实时监测上下文大小,优先丢弃大工具结果
chat-factory.ts — 工厂决定谁上场
两个引擎不是并存竞争,而是由 chat-factory.ts 的 globalPAVREnabled 全局开关决定 createChatEngine() 返回哪一个。
export function createChatEngine(usePAVR?: boolean, config?: Config) {
const shouldUsePAVR = usePAVR ?? globalPAVREnabled
if (shouldUsePAVR) {
return new EnhancedChatEngine(config)
} else {
return new ChatEngine(config)
}
}
命令 /pavr 只是一个快捷开关,实际修改的就是 globalPAVREnabled 这个标志位。
💡 关键理解:
EnhancedChatEngine = ChatEngine + PAVR 机制。两者共享底层工具调用(executeTool)和 API 调用逻辑,区别仅在于"是否先输出计划"。
📐 整体架构图
├── parseArgs()
├── createChatEngine()
│
│ ┌─────────────────── globalPAVREnabled ───────────────────┐
│ │ │
│ │ true? false? │
│ │ ↓ ↓ │
│ │ EnhancedChatEngine ChatEngine │
│ │ (chat-enhanced.ts) (chat.ts) │
│ │ • PAVR 计划层 • 普通工具循环 │
│ │ • 80轮 maxTurns • 80轮 maxTurns │
│ │ • token感知截断 • token感知截断 │
│ └─────────────────────────────────────────────────────────┘
│
├── if -p 单次模式? → engine.chat() → exit
│
└── else REPL 模式: → replLoop()(engine) → I/O 循环
│
└── repl.ts: engine.chat() 驱动对话
⚠️ 注意:
repl.ts 本身不创建引擎,它只是接收 cli.ts 传入的 engine 实例。repl.ts 中的 new ChatEngine() 仅在用户执行 /model 切换模型时用于重新初始化。
📝 总结
ChatEngine:基础引擎,普通工具循环,适合简单快速的任务
EnhancedChatEngine:增强引擎,PAVR 计划层,适合复杂敏感任务
/pavr 命令切换全局开关,控制使用哪个引擎
- 两引擎共享工具调用层和 API 调用逻辑,主要区别在于对话循环策略
- 两者都实现了 token 感知截断(110K 上限)和 80 轮 maxTurns 限制
来源:CmdCode V0.5 源码分析 · chat.ts / chat-enhanced.ts / chat-factory.ts