Daemon 启动序列

运行 zeroclaw daemon start 后的初始化顺序:

sequenceDiagram participant CLI as zeroclaw CLI participant CFG as Config Loader participant RT as Runtime participant MEM as Memory Engine participant CH as Channel Adapters participant GW as Gateway Server participant SCH as Cron Scheduler participant SOP as SOP Engine participant AG as Agent Loop CLI->>CFG: 加载 ~/.zeroclaw/config.toml CFG-->>CLI: Config 验证通过 CLI->>RT: 初始化 Runtime RT->>MEM: 打开 SQLite + 加载向量索引 MEM-->>RT: Memory Ready RT->>CH: 启动配置的 Channel Adapters CH-->>RT: Adapters Connected RT->>GW: 启动 HTTP/WebSocket 服务器 (:8080) GW-->>RT: Gateway Ready RT->>SCH: 加载 Cron 任务表 SCH-->>RT: Scheduler Running RT->>SOP: 注册 SOP 规则 SOP-->>RT: SOP Engine Ready RT->>AG: 为每个 Agent 实例化 AgentBuilder AG-->>RT: Agents Ready RT-->>CLI: Daemon Running ✓ Note over CLI,AG: 进入事件循环,等待输入

Agent Loop 主流程

每次收到消息后,Agent Loop(process_message)的完整执行路径:

flowchart TD IN([📨 收到消息\nChannel / Gateway / CLI]) --> CLASS[意图分类\nclassifier.rs] CLASS --> CTX[构建上下文\nbuild_context] CTX --> MEM_LOAD[记忆检索\nmemory_loader\n向量 0.7 + 关键词 0.3] MEM_LOAD --> HW_CTX{硬件 Agent?} HW_CTX -- 是 --> HW[注入 GPIO/I2C\n引脚别名 + 数据手册] HW_CTX -- 否 --> FILTER HW --> FILTER[工具过滤管道\napply_policy_tool_filter\nfilter_tool_specs_for_turn] FILTER --> SYS[构建 System Prompt\nsystem_prompt.rs] SYS --> LLM[调用 LLM Provider\nstream_chat] subgraph STREAM["流式输出处理"] LLM --> GUARD[StreamTextGuard\n检测内嵌 Tool Protocol] GUARD --> DELTA[转发 delta 给用户] end GUARD --> PARSE{响应类型} PARSE -- 纯文本 --> STORE[存储记忆\nmemory.store] PARSE -- 含 Tool Call --> TC[Tool Call 解析\ntool_call_parser] TC --> RISK{风险评级} RISK -- 低风险 --> EXEC[执行工具\ntool_execution.rs] RISK -- 中风险 --> APPR[请求审批\napproval_manager] RISK -- 高风险 --> BLOCK([🚫 阻断]) APPR -- 批准 --> EXEC APPR -- 拒绝 --> RESP EXEC --> RECEIPT[生成 Tool Receipt\n加密凭证] RECEIPT --> ITER{迭代次数\n≤ MAX_TOOL_ITERATIONS?} ITER -- 是, 继续 --> LLM ITER -- 否 --> RESP STORE --> RESP([💬 返回响应]) style IN fill:#1a3020,stroke:#56d364,color:#e6edf3 style RESP fill:#1a3020,stroke:#56d364,color:#e6edf3 style BLOCK fill:#3a1a1a,stroke:#f78166,color:#e6edf3 style STREAM fill:#1a2232,stroke:#79c0ff,color:#e6edf3
DEFAULT_MAX_TOOL_ITERATIONS
10
单次请求最大工具迭代次数
STREAM_CHUNK_MIN_CHARS
80
流式转发最小字符块
MAX_MALFORMED_TOOL_PROTOCOL_RETRIES
2
格式错误 Tool Call 最大重试次数
PROGRESS_MIN_INTERVAL_MS
500ms
进度更新最小间隔

运行时状态机

Agent 在生命周期内的状态转换:

stateDiagram-v2 [*] --> Idle : 初始化完成 Idle --> Processing : 收到消息 state Processing { [*] --> Classifying Classifying --> BuildingContext BuildingContext --> CallingLLM CallingLLM --> Streaming state Streaming { [*] --> ForwardingDelta ForwardingDelta --> DetectingToolCall DetectingToolCall --> ForwardingDelta : 纯文本继续 DetectingToolCall --> [*] : Tool Call 检测到 } Streaming --> ExecutingTools : 有 Tool Call Streaming --> StoringMemory : 无 Tool Call ExecutingTools --> AwaitingApproval : 中/高风险 AwaitingApproval --> ExecutingTools : 用户批准 AwaitingApproval --> StoringMemory : 用户拒绝 ExecutingTools --> CallingLLM : 工具结果 → 继续迭代 ExecutingTools --> StoringMemory : 达到 MAX_TOOL_ITERATIONS StoringMemory --> [*] } Processing --> Idle : 响应完成 Idle --> ScheduledTask : Cron 触发 ScheduledTask --> Processing : 执行例程 Idle --> SOPTriggered : SOP 事件匹配 SOPTriggered --> Processing : 执行 SOP 流程 Processing --> Error : 异常 Error --> Idle : 错误处理完毕 Idle --> [*] : 关闭

Tool 过滤管道

每次 LLM 调用前,工具列表经过三层过滤:

flowchart LR ALL[所有注册工具\nVec<Tool>] --> F1 subgraph F1["① SecurityPolicy 过滤\napply_policy_tool_filter"] P1{在 allowlist?} P1 -- 否 --> DROP1[❌ 丢弃] P1 -- 是 --> P2{在 denylist?} P2 -- 是 --> DROP2[❌ 丢弃] P2 -- 否 --> PASS1[✓ 通过] end PASS1 --> F2 subgraph F2["② MCP 关键词过滤\nfilter_tool_specs_for_turn"] P3{消息含 MCP\n激活关键词?} P3 -- 否 --> DROP3[❌ 排除 MCP 工具] P3 -- 是 --> PASS2[✓ 包含 MCP 工具] end DROP3 --> F3 PASS2 --> F3 subgraph F3["③ 能力 Allowlist 过滤\nfilter_by_allowed_tools(可选)"] P4{配置了\nallowed_tools?} P4 -- 否 --> PASS3[✓ 全部通过] P4 -- 是 --> P5{在 allowed_tools?} P5 -- 否 --> DROP4[❌ 丢弃] P5 -- 是 --> PASS3 end PASS3 --> OUT[最终工具列表\n注入 System Prompt] style ALL fill:#1a2832,stroke:#79c0ff,color:#e6edf3 style OUT fill:#1a3020,stroke:#56d364,color:#e6edf3

Tool 执行流程

LLM 返回 Tool Call 后的并行/串行执行决策:

flowchart TD TC[Tool Calls 列表] --> PARSE[zeroclaw-tool-call-parser\n解析 JSON 参数] PARSE --> VALID{参数合法?} VALID -- 否 --> RETRY{重试次数\n≤ MAX_MALFORMED?} RETRY -- 是 --> TC RETRY -- 否 --> ERR([返回错误给 LLM]) VALID -- 是 --> RISK_CHECK[SecurityPolicy.check_risk\n评估每个 Tool Call] RISK_CHECK --> GROUP{并行还是串行?} GROUP -- 无依赖 → 并行 --> PAR subgraph PAR["并行执行 (Tokio spawn)"] T1[Tool A] & T2[Tool B] & T3[Tool C] end GROUP -- 有依赖 → 串行 --> SEQ subgraph SEQ["串行执行"] S1[Tool 1] --> S2[Tool 2] --> S3[Tool 3] end PAR --> HOOK[HookRunner\n执行前后钩子] SEQ --> HOOK HOOK --> RECEIPT[生成加密 Tool Receipt] RECEIPT --> RESULTS[收集所有工具结果] RESULTS --> HISTORY[追加 tool_result 到 History] HISTORY --> NEXT([下一次 LLM 迭代]) style ERR fill:#3a1a1a,stroke:#f78166,color:#e6edf3 style NEXT fill:#1a3020,stroke:#56d364,color:#e6edf3

Memory 检索流程

每次 Agent Loop 开始时,从内存引擎检索相关历史:

flowchart TD QUERY[当前用户消息] --> EMBED[生成查询向量\n内置向量引擎(无外部依赖)] EMBED --> VEC[向量相似度搜索\nSQLite 向量索引\nweight: 0.7] QUERY --> KW[关键词提取\nBM25 搜索\nweight: 0.3] VEC --> MERGE[混合分数合并\nscore = 0.7×vec + 0.3×bm25] KW --> MERGE MERGE --> DECAY[时间衰减加权\n近期记忆优先] DECAY --> FILTER_MEM{是自主运行?} FILTER_MEM -- 是 --> EXCL[排除对话条目\n仅保留事实性记忆] FILTER_MEM -- 否 --> RANK[按得分排序\n取 Top-K] EXCL --> RANK RANK --> INJECT[注入 System Prompt\n相关记忆上下文] INJECT --> LOOP([继续 Agent Loop]) style QUERY fill:#1a2232,stroke:#79c0ff,color:#e6edf3 style LOOP fill:#1a3020,stroke:#56d364,color:#e6edf3
混合搜索权重

向量相似度 0.7 + 关键词 0.3,平衡语义理解与精确匹配

零外部依赖

向量嵌入完全内置,无需 Pinecone / Qdrant 等外部向量数据库

自主模式过滤

Daemon/自主运行时排除对话记录,只用事实性知识避免噪声

安全审批流程

三级风险模型决定工具调用的处理方式:

flowchart TD CALL[Tool Call 请求] --> SANDBOX{在 Workspace\n目录内?} SANDBOX -- 否 --> BLOCK2([🚫 直接阻断\n文件系统越界]) SANDBOX -- 是 --> CMD{是 Shell 命令?} CMD -- 是 --> ALLOW{在命令\nAllowlist 内?} ALLOW -- 否 --> BLOCK3([🚫 阻断\n命令不在白名单]) ALLOW -- 是 --> RISK CMD -- 否 --> RISK[SecurityPolicy.check_risk\n评估操作风险等级] RISK --> LEVEL{风险等级} LEVEL -- 低 --> AUTO([✅ 自动执行]) LEVEL -- 中 --> CHECK_MODE{autonomy_level} LEVEL -- 高 --> BLOCK4([🚫 直接阻断]) CHECK_MODE -- supervised --> ASK[发送审批请求\n给用户/审批方] CHECK_MODE -- autonomous --> AUTO CHECK_MODE -- strict --> BLOCK5([🚫 阻断]) ASK --> DECISION{用户决定} DECISION -- 批准 --> SIGN[ApprovalManager 签名] DECISION -- 拒绝 --> DENY([❌ 拒绝执行\n返回原因给 LLM]) SIGN --> OS_SAND[OS 级沙箱\nLandlock/Bubblewrap\nSeatbelt/Docker] OS_SAND --> EXEC([⚡ 执行 Tool]) style BLOCK2 fill:#3a1a1a,stroke:#f78166,color:#e6edf3 style BLOCK3 fill:#3a1a1a,stroke:#f78166,color:#e6edf3 style BLOCK4 fill:#3a1a1a,stroke:#f78166,color:#e6edf3 style BLOCK5 fill:#3a1a1a,stroke:#f78166,color:#e6edf3 style AUTO fill:#1a3020,stroke:#56d364,color:#e6edf3 style EXEC fill:#1a3020,stroke:#56d364,color:#e6edf3 style DENY fill:#3a2a1a,stroke:#e3b341,color:#e6edf3

消息通道流程

外部消息(如 Telegram)进入系统到返回响应的完整路径:

sequenceDiagram participant USR as 用户 (Telegram) participant CH as Channel Adapter\n(zeroclaw-channels) participant RT as Runtime Dispatcher participant AG as Agent Loop participant LLM as LLM Provider participant TOOL as Tool Executor participant MEM as Memory Engine USR->>CH: 发送消息 CH->>RT: 标准化 IncomingMessage RT->>RT: 路由到对应 Agent (by alias) RT->>AG: process_message(msg, session_id) AG->>MEM: 检索相关记忆 (hybrid search) MEM-->>AG: 记忆上下文 AG->>LLM: stream_chat(history + context + tools) LLM-->>AG: 流式响应 delta... loop 工具迭代 (最多 10 次) AG->>AG: 检测 Tool Call AG->>TOOL: 执行工具 TOOL-->>AG: 工具结果 AG->>LLM: 追加 tool_result,继续 LLM-->>AG: 下一轮响应 end AG->>MEM: 存储对话记忆 AG-->>RT: 最终响应文本 RT-->>CH: 发送响应 CH-->>USR: 回复消息 Note over AG,LLM: 响应通过 StreamTextGuard 实时转发给用户

SOP 引擎触发流程

Standard Operating Procedures:事件触发的自动化工作流:

flowchart TD EVENTS[事件来源] --> E1[Channel 消息] EVENTS --> E2[Cron 定时触发] EVENTS --> E3[Webhook 回调] EVENTS --> E4[Memory 关键词匹配] E1 & E2 & E3 & E4 --> MATCH[SOP Engine\n规则匹配] MATCH --> MATCHED{找到匹配\nSOP 规则?} MATCHED -- 否 --> NORMAL[正常 Agent Loop] MATCHED -- 是 --> PARSE_SOP[解析 SOP 步骤定义] PARSE_SOP --> GATE{有审批门控\napproval_gate?} GATE -- 是 --> WAIT[等待人工确认] GATE -- 否 --> STEPS WAIT -- 确认 --> STEPS WAIT -- 拒绝 --> ABORT([中止 SOP]) STEPS[按序执行 SOP 步骤] --> STEP1[Step 1\n执行动作] STEP1 --> CHECK1{步骤成功?} CHECK1 -- 否 --> FALLBACK[执行 Fallback 逻辑] CHECK1 -- 是 --> STEP2[Step 2...] STEP2 --> COMPLETE([SOP 完成\n存储执行记录]) style ABORT fill:#3a1a1a,stroke:#f78166,color:#e6edf3 style COMPLETE fill:#1a3020,stroke:#56d364,color:#e6edf3 style NORMAL fill:#1a2232,stroke:#79c0ff,color:#e6edf3