Pi Agent 运行时
一句话概括
嵌入式 Pi Agent 运行时是编排每次 LLM 调用的执行引擎 — 它组装 prompt、管理认证 profile、处理重试、触发压缩,并追踪 token 用量。
职责
- 执行 LLM 调用循环:构建 system prompt → 发送给模型 → 处理响应 → 处理工具调用 → 重复
- 管理多 profile 认证,在失败时自动轮换(速率限制、认证错误、账单问题)
- 检测并通过自动压缩和工具结果截断来恢复上下文溢出
- 跨重试追踪 token 用量,确保上下文大小报告准确(避免累积缓存膨胀)
- 协调 thinking level 解析和模型不支持时的降级回退
架构图
关键源码文件
数据流
入站
内部流程(每次 LLM 调用)
出站
Token 关键机制
1. 用量累积策略(run.ts:83-179)
UsageAccumulator 跨重试追踪 token,有一个关键细节:
这在 GitHub issue #13698 中有记录。没有此修复,一个 5 次工具调用的轮次会报告 ~1M tokens 而非 ~200k。
2. 上下文溢出恢复(run.ts:666-846)
三层恢复策略:
关键约束:overflowCompactionAttempts 跨层永不重置(防止无界压缩循环,参考:OC-65)。
3. 压缩内部实现(compaction.ts)
4. 压缩设置(pi-settings.ts)
5. 工具策略管道(tool-policy-pipeline.ts)
每次 LLM 调用前过滤可用工具的 7 步级联:
更少工具 = 更少 JSON schema 在 API 调用中 = 更低的每次调用固定 token 成本。
6. System prompt 构建(system-prompt.ts)
三种模式控制 prompt 大小:
"full" 模式中 token 较重的章节:
- Skills 目录(如果加载了 skills):~1,000-5,000 tokens
- 上下文文件(SOUL.md、RULES.md):0-5,000+ tokens,无截断
- Messaging 章节:~200-500 tokens(详细路由 + message 工具说明)
- 工具摘要:~500-800 tokens(24 个核心工具 × 约 30 tokens)
与其他模块的关系
-
依赖:
auto-reply/— 调用runEmbeddedPiAgent()作为执行引擎config/— 读取 OpenClawConfig 获取所有设置skills/— 接收 skills 快照用于 prompt 注入memory/— 通过 Pi SDK hooks 注入记忆上下文@mariozechner/pi-agent-core— 实际的 LLM 交互 SDK@mariozechner/pi-coding-agent—estimateTokens()、generateSummary()
-
被依赖:
auto-reply/get-reply-run.ts— 主要调用方cron/service/timer.ts— 心跳调用同一运行时- 任何子 agent 生成都经过此运行时
重试逻辑汇总
Token 优化影响
此模块是 token 消耗的中央控制点:
我的认知盲区
-
runEmbeddedAttempt()中 Pi SDK 会话生命周期的确切流程 —session.run()内部在 SDK 中,不在 OpenClaw 源码中 -
compact.ts中compactEmbeddedPiSessionDirect()与compaction.ts函数的区别 — 需要阅读桥接代码 - 插件 hooks(
before_agent_start、before_model_resolve)— 它们能多大程度修改运行时行为和 token 预算 -
streamParams以及流式传输如何影响 token 计数 - Pi SDK 的
estimateTokens()是否使用 tiktoken 还是 chars/4 启发式 — 精度影响压缩触发时机 -
tool-result-truncation.ts— 精确的截断策略和大小阈值
相关贡献
- 暂无
变更频率
run.ts:高 — 错误处理和重试逻辑随着新边缘情况的发现而频繁变更(如 OC-65 压缩循环、#13698 用量膨胀)system-prompt.ts:中 — 随着功能发布添加新章节(reactions、sandbox、model aliases)compaction.ts:中 — 压缩策略随模型和上下文窗口变化而演进tool-policy-pipeline.ts:低 — 7 步级联是稳定的;变更通常在策略定义中,而非管道本身defaults.ts:低 — 常量很少变更(200k 上下文与 Claude 模型限制挂钩)