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 --> [*] : 关闭
每次 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
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