Code Reader
首页
帮助
设计文档
首页
帮助
设计文档
  • Pi Agent 运行时架构

Pi Agent 运行时架构

Moltbot 的 AI Agent 运行时,基于 pi-coding-agent SDK

概述

Pi Agent 运行时是 Moltbot 的核心 AI 处理引擎,基于 @mariozechner/pi-coding-agent SDK 构建。它通过消息队列、沙箱隔离、工具策略和多层级故障转移机制,实现了高可用的代码辅助代理。

设计目标

  • 流式处理: 支持文本和工具结果的实时流式返回
  • 沙箱隔离: 非主会话可在 Docker 沙箱中运行
  • 故障转移: 多层级 API Key 失效转移和模型回退
  • 工具策略: 细粒度的工具权限控制
  • 上下文管理: 智能的历史修剪和压缩

Agent 运行流程

主运行流程

入口函数: runEmbeddedPiAgent文件: src/agents/pi-embedded-runner/run.ts

关键步骤详解

1. Lane 解析

文件: src/agents/pi-embedded-runner/lanes.ts

const sessionLane = resolveSessionLane(params.sessionKey?.trim() || params.sessionId);
const globalLane = resolveGlobalLane(params.lane);

// 目的:防止同 session 并发冲突,同时限制全局资源竞争
// Session Lane: session:{key}
// Global Lane: 可配置,默认为 "main"

2. 模型解析

文件: src/agents/pi-embedded-runner/model.ts

const { model, error, authStorage, modelRegistry } = resolveModel(
  provider,
  modelId,
  agentDir,
  params.config,
);

if (!model) {
  throw new Error(error ?? `Unknown model: ${provider}/${modelId}`);
}

3. 上下文窗口验证

文件: src/agents/context-window-guard.ts

const ctxInfo = resolveContextWindowInfo({
  cfg: params.config,
  provider,
  modelId,
  modelContextWindow: model.contextWindow,
  defaultTokens: DEFAULT_CONTEXT_TOKENS,
});

const ctxGuard = evaluateContextWindowGuard({
  info: ctxInfo,
  warnBelowTokens: CONTEXT_WINDOW_WARN_BELOW_TOKENS,
  hardMinTokens: CONTEXT_WINDOW_HARD_MIN_TOKENS,
});

if (ctxGuard.shouldBlock) {
  throw new FailoverError(
    `Model context window too small (${ctxGuard.tokens} tokens). Minimum is ${CONTEXT_WINDOW_HARD_MIN_TOKENS}.`,
    { reason: "unknown", provider, model: modelId },
  );
}

工具调用机制

工具创建流程

文件: src/agents/pi-tools.ts

工具策略优先级

从高到低:

  1. Profile 策略: tools.profile
  2. Provider Profile 策略: tools.byProvider[{provider}].profile
  3. Agent 策略: agents[{id}].tools.allow
  4. Agent Provider 策略: agents[{id}].tools.byProvider[{provider}].allow
  5. Group 策略: channel/group 特定
  6. Sandbox 策略: tools.sandbox.tools.allow
  7. Subagent 策略: subagent 专用

工具执行与流式返回

文件: src/agents/pi-embedded-subscribe.ts

subscribeEmbeddedPiSession({
  session,
  runId,
  onPartialReply,      // 文本增量回调
  onToolResult,       // 工具结果回调
  onAgentEvent,       // Agent 事件回调
  ...
})

事件流处理

上下文管理

Session 上下文构建

Session Manager (@mariozechner/pi-coding-agent):

SessionManager.open(sessionFile)
createAgentSession({
  cwd,
  agentDir,
  model,
  systemPrompt,
  tools: builtInTools,
  customTools: allCustomTools,
  sessionManager,
  settingsManager,
  ...
})

History 修剪逻辑

修剪管道 (src/agents/pi-embedded-runner/run/attempt.ts):

修剪策略

  1. Sanitize History (src/agents/pi-embedded-runner/google.ts)

    • Google 风格 tool_call/tool_result 格式转换
  2. Validate Turns

    • Gemini: 强制 role 交替
    • Anthropic: 确保最小 1 个 assistant message
  3. DM History Limit (src/agents/pi-embedded-runner/history.ts)

    limitHistoryTurns(messages, limit)
    
    • 基于配置的 dmHistoryLimit 限制用户回合数
    • 保留最近 N 个用户消息及相关响应

System Prompt 合成

文件: src/agents/pi-embedded-runner/system-prompt.ts

buildEmbeddedSystemPrompt({
  workspaceDir,
  tools,
  runtimeInfo: { host, os, arch, { node, model, channel, capabilities, channelActions },
  sandboxInfo,
  skillsPrompt,
  heartbeatPrompt,
  docsPath,
  reactionGuidance,
  messageToolHints,
  contextFiles,
{  ...
})

动态注入内容

  • 工具摘要和描述
  • 运行时信息(主机名、OS、Node 版本)
  • 沙箱隔离状态
  • 通道能力
  • 技能提示
  • 心跳提示(仅默认 agent)
  • 上下文文件内容

模型认证和故障转移

Auth Profile 系统

文件: src/agents/model-auth.ts

Auth Source 优先级

  1. 指定的 profileId
  2. Auth Profile 顺序 (按配置)
  3. 环境变量 (provider-specific)
  4. 配置中的 models.providers[{provider}].apiKey
  5. AWS SDK 链 (Bedrock 默认)

Failover 机制

故障检测与切换 (src/agents/pi-embedded-runner/run.ts):

Failover Reasons

  • rate_limit: Rate limited (带 cooldown)
  • auth: Authentication failed
  • timeout: Request timeout
  • unknown: 其他错误

Rate Limit 处理

Cooldown 管理 (src/agents/auth-profiles/usage.ts):

calculateAuthProfileCooldownMs(failureReason, failureCount)
markAuthProfileCooldown({ store, profileId, failureReason, cfg, agentDir })
isProfileInCooldown(authStore, profileId)

Cooldown 策略

const BASE_COOLDOWN_MS = 60_000; // 1 分钟
const MAX_COOLDOWN_MS = 5 * 60_000; // 5 分钟

// 基于失败原因和失败次数指数退避
// 限制最大冷却时间

Sandbox 集成

Sandbox 运行时状态

文件: src/agents/sandbox/runtime-status.ts

resolveSandboxRuntimeStatus({ cfg, sessionKey })

shouldSandboxSession(cfg, sessionKey, mainSessionKey)

判定逻辑

  • mode: off: 不启用
  • mode: all: 所有 session 启用
  • mode: non-main: 非主 session 启用

容器生命周期

文件: src/agents/sandbox/docker.ts

ensureSandboxContainer({
  sessionKey,
  workspaceDir,
  agentWorkspaceDir,
  cfg
})

配置哈希验证

  • 计算 Docker 配置和挂载点哈希
  • 与现有容器标签对比
  • 不匹配时重建(除非最近活跃)

工作空间映射

文件: src/agents/sandbox/context.ts

host: /home/user/workspace
agentWorkspaceDir: /home/user/.clawdbot/agents/main/workspace
sandboxWorkspaceDir: /home/user/.clawdbot/sandboxes/session-xyz/workspace

Mode: rw (读写)
  - host -> container: /workspace (rw)

Mode: ro (只读)
  - host -> container: /agent (ro)
  - sandboxWorkspaceDir -> container: /workspace (rw)

Mode: none (无宿主访问)
  - sandboxWorkspaceDir -> container: /workspace (rw)

工具策略隔离

文件: src/agents/sandbox/tool-policy.ts

resolveSandboxToolPolicyForAgent(cfg, agentId)
isToolAllowed(policy, toolName)

策略来源

  1. Agent 级: agents[{id}].tools.sandbox.tools
  2. 全局级: tools.sandbox.tools
  3. 默认: ["*"] (允许所有),但 ["!bash", "!exec"] (阻止危险工具)

Deny 优先

  • 先检查 deny 列表
  • 如果不在 deny 中,再检查 allow 列表
  • Allow 为空时,默认允许

关键类型定义

Run Params

文件: src/agents/pi-embedded-runner/run/types.ts

{
  sessionId, sessionKey,
  messageChannel, messageProvider,
  agentAccountId, messageTo, messageThreadId,
  groupId, groupChannel, groupSpace,
  sessionFile, workspaceDir, agentDir,
  prompt, images,
  provider, modelId, model,
  authStorage, modelRegistry,
  thinkLevel, reasoningLevel,
  timeoutMs, runId, abortSignal,
  onPartialReply, onToolResult, onAgentEvent,
  ...
}

Sandbox Context

文件: src/agents/sandbox/types.ts

{
  enabled, sessionKey,
  workspaceDir, agentWorkspaceDir,
  workspaceAccess, // "none" | "ro" | "rw"
  containerName, containerWorkdir,
  docker, tools,
  browserAllowHostControl,
  browser? // { bridgeUrl, noVncUrl, containerName }
}

Auth Profile

文件: src/agents/model-auth.ts

{
  apiKey?, profileId?, source,
  mode: "api-key" | "oauth" | "token" | "aws-sdk"
}

代码路径引用

功能文件路径
主运行函数src/agents/pi-embedded-runner/run.ts
尝试执行src/agents/pi-embedded-runner/run/attempt.ts
Lane 解析src/agents/pi-embedded-runner/lanes.ts
模型解析src/agents/pi-embedded-runner/model.ts
System Promptsrc/agents/pi-embedded-runner/system-prompt.ts
History 修剪src/agents/pi-embedded-runner/history.ts
工具创建src/agents/pi-tools.ts
事件订阅src/agents/pi-embedded-subscribe.ts
Auth Profilesrc/agents/model-auth.ts
Failover 错误src/agents/failover-error.ts
Sandbox 上下文src/agents/sandbox/context.ts
Docker 管理src/agents/sandbox/docker.ts
工具策略src/agents/sandbox/tool-policy.ts