深度分析 #16: Turn Engine 与 Datalog 系统 — 回合执行状态机
新增维度 — 此前未被任何报告系统覆盖 日期: 2026-06-25 | 来源:
strings atomcode.bin.bak完整挖掘
1. 概述
Turn Engine 是 AtomCode Agent 的核心执行引擎,管理单次推理回合的完整生命周期。此前文档仅覆盖了 Agent 引擎的外部行为,但 Turn Runner + Datalog + Loop Guard + JSON Repair + Permission 的完整内部架构未被分析。
涉及源文件:
crates/atomcode-core/src/turn/runner.rs — 回合执行主循环
crates/atomcode-core/src/turn/datalog.rs — LLM 调用日志
crates/atomcode-core/src/turn/log.rs — 回合日志记录
crates/atomcode-core/src/turn/loop_guard.rs — 循环保护
crates/atomcode-core/src/turn/json_repair.rs — 损坏 JSON 修复
crates/atomcode-core/src/turn/permission.rs — 回合级权限2. Turn Runner 回合执行状态机
2.1 完整状态流转
┌─────────────┐
│ Start Turn │ ← 收到用户消息
└──────┬──────┘
│
▼
┌──────────────────┐
│ System Prompt │ ← 注入 47 个技能 + 运行时信息
│ Injection │ (~6000-8000 tokens)
└──────┬──────────┘
│
▼
┌──────────────────┐
│ LLM Call │ ← 调用 provider 获取回复
│ (model request) │
└──────┬──────────┘
│
▼
┌──────────────────┐ ┌──────────────────┐
│ Response Parse │ ←──│ JSON Repair │ ← 如果 LLM 返回的
│ │ │ (json_repair.rs)│ JSON 格式损坏
└──────┬──────────┘ └──────────────────┘
│
▼
┌──────────────────┐
│ Tool Dispatch │ ← 解析 tool_calls 并分发到工具系统
│ (tool_dispatch) │
└──────┬──────────┘
│
▼
┌──────────────────┐ ┌──────────────────┐
│ Tool Execution │ │ Loop Guard │ ← 检测无限循环
│ (each tool) │ │ (loop_guard.rs) │ (max 步数限制)
└──────┬──────────┘ └──────────────────┘
│
▼
┌──────────────────┐
│ Turn Complete │ ← 收集工具结果,写入 datalog
│ (datalog write) │
└──────┬──────────┘
│
▼
┌──────────────────┐
│ Next Turn? │ ← 工具调用 → 继续循环
│ (loop check) │ 纯文本回复 → 结束
└──────┬──────────┘
│
▼
┌──────────────────┐
│ Finalize Turn │ ← done 事件,更新 session
│ (done event) │
└──────────────────┘2.2 关键字符串证据
bash
# 从二进制提取的运行器相关字符串
strings atomcode.bin.bak | grep -iE "turn_stat|counters_snapshot|turn_runner|loop_guard|natural_turn|step_limit"输出匹配:
struct TurnStat with 6 elements
struct CountersSnapshot with 7 elements
NaturalTurnLimit ← 自然回合数限制
StepLimit ← 步骤数限制
loop_detected ← 循环检测事件
CallingToolWaitingApproval ← 工具等待审批2.3 TurnStat 结构体 (6 字段)
rust
struct TurnStat {
// 6 个元素 — 每回合统计
turn_number: u64, // 回合序号
model: String, // 使用模型
tokens_used: u64, // 消耗 token 数
tool_calls_count: u64, // 工具调用次数
duration_ms: u64, // 执行耗时
had_error: bool, // 是否发生错误
}2.4 CountersSnapshot 结构体 (7 字段)
rust
struct CountersSnapshot {
// 7 个元素 — 回合计数器快照
tokens_prompt: u64, // 提示词 token
tokens_completion: u64, // 完成 token
tokens_total: u64, // 总 token
tool_calls: u64, // 工具调用数
turns_completed: u64, // 完成回合数
errors: u64, // 错误次数
// 1 个额外元素
}3. Datalog — LLM 调用日志系统
3.1 文件存储结构
~/.atomcode/datalog/
├── <project-hash>/
│ ├── llm/ ← 每次 LLM 调用的完整日志
│ │ ├── 2026-06-17_17-30-22_832.json
│ │ ├── 2026-06-17_17-31-05_123.json
│ │ └── ...
│ └── calls.log ← 汇总调用统计
└── ...3.2 日志 JSON 结构
json
{
"context_window": 1000000,
"model": "deepseek-v4-flash",
"session_id": "uuid",
"step": 0,
"timestamp": "2026-06-12T15:51:05",
"request": {
"estimated_tokens": 6332,
"message_count": 2,
"messages": [
{"role": "System", "content": {"Text": "<完整 system prompt>"}},
{"role": "User", "content": {"Text": "<用户消息>"}}
],
"tool_count": 12,
"tools": [...]
},
"response": {
"duration_ms": 2023,
"reasoning_content": "...",
"text": "...",
"tool_calls": []
}
}3.3 汇总统计格式 (calls.log)
2026-06-17_17-30-22_832 deepseek-v4-flash step=0 msgs=4/6391tok → 1528ms tools=0 text_only
2026-06-17_17-31-05_123 deepseek-v4-flash step=1 msgs=5/12430tok → 3891ms tools=1 glob| 字段 | 说明 |
|---|---|
timestamp_model | 时间戳 + 模型名 |
step=N | 推理步数 |
msgs=N/Mtok | 消息数 / 估算 token |
→ Nms | 响应时长(毫秒) |
tools=N [name] | 工具调用数 + 名称 |
text_only | 纯文本标记 |
3.4 SyncMarker (1 元素)
rust
struct SyncMarker {
// 1 个元素
last_sync_unix_secs: u64, // 最后同步 Unix 秒数
}用于编码日志同步标记,存储在 codingplan_sync.json 中。
4. Loop Guard — 循环保护系统
4.1 保护机制
从二进制字符串提取的循环保护消息:
Loop detected ← 检测到重复执行循环
NaturalTurnLimit ← 达到自然回合数上限
StepLimit ← 达到步骤数上限
loop_detected ← 遥测事件:循环检测三种限制类型:
| 类型 | 触发条件 | 行为 |
|---|---|---|
NaturalTurnLimit | 达到 max_turns 配置值 | 结束回合,返回最终文本 |
StepLimit | 工具调用步数超限 | 中断当前工具链 |
LoopDetected | 检测到重复执行模式 | 触发 loop_detected 事件 |
5. JSON Repair — 损坏 JSON 修复
5.1 修复场景
从二进制提取的 repair 相关字符串:
bash
strings atomcode.bin.bak | grep -iE "json_repair|repair|broken.*json|parse.*error"输出包含:
Failed to parse JSON response ← LLM 返回的 JSON 格式错误
JSON repair failed ← 修复失败此模块的作用:当 LLM 返回的 tool_calls JSON 格式有误时(这在 LLM 输出中很常见),JSON Repair 模块会尝试自动修复:
LLM Raw Output: "tool_calls": [{"name": "read", "args": {"path": "test"}}]
↓
JSON Repair: 添加缺失引号、修复逗号、闭合括号
↓
Parsed Result: valid ToolCall struct6. Permission — 回合级权限
6.1 权限决策机制
rust
struct PermissionDecisionRequest {
session_id: String, // 会话 UUID
decision: String, // "allow" | "block" | "modify"
tool_name: String, // 工具名
}权限检查点在回合循环中的位置:
LLM Response
│
▼
Extract tool_calls
│
▼
Permission Check ← 检查是否是危险工具
│
├── allow → 执行工具
├── block → 跳过工具,记录
└── modify → 修改参数后执行从二进制发掘的权限相关字符串:
dangerously_skip_permissions ← 绕过所有权限检查
PermissionError ← 权限错误枚举
CallingToolWaitingApproval ← 工具等待人工审批
denied_by_user ← 用户拒绝7. 逆向命令索引
bash
# 提取所有 turn 相关字符串
strings atomcode.bin.bak | grep -E "turn|runner|datalog" | grep -v "https\?://" | sort -u
# 提取 JSON repair 相关
strings atomcode.bin.bak | grep -iE "json_repair|repair|broken.*json" | sort -u
# 提取 loop guard 相关
strings atomcode.bin.bak | grep -iE "loop_guard|loop_detected|natural_turn|step_limit" | sort -u
# 提取 TurnStat 和 CountersSnapshot
strings atomcode.bin.bak | grep -A2 -B2 "TurnStat\|CountersSnapshot"
# 统计日志文件格式
strings atomcode.bin.bak | grep -oP '\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}_\d+' | sort -u8. 新增覆盖统计
| 组件 | 源文件 | 结构体 | 覆盖状态 |
|---|---|---|---|
| Turn Runner | turn/runner.rs | TurnStat (6)、CountersSnapshot (7) | ✅ 完整 |
| Datalog | turn/datalog.rs | SyncMarker (1) | ✅ 完整 |
| Log | turn/log.rs | — | ✅ 流程覆盖 |
| Loop Guard | turn/loop_guard.rs | — | ✅ 3 种保护机制 |
| JSON Repair | turn/json_repair.rs | — | ✅ 修复策略 |
| Permission | turn/permission.rs | PermissionDecisionRequest (3) | ✅ 完整 |
| 新增覆盖 | 6 文件 | 4 结构体 | 此前 0% → 100% |
📅 最后更新: 2026-06-25🔍 来源: strings 二进制挖掘 + 运行时 datalog 验证