请求生命周期
用户发送消息与智能体回复之间发生了什么:完整路径,并标注了流式传输、工具调用和安全门控。
入站
flowchart LR
A[External event] -->|webhook / push / poll / WS| B[Channel adapter]
B -->|decode, dedup, pair-check| C[Inbound envelope]
C -->|workspace binding| D[Runtime: process_message]
通道适配器(例如 discord.rs、telegram.rs、email_channel.rs)接收平台原生事件,并将其转换为统一的外部信封。适配器处理:
- 解码:平台特定负载 → 规范消息格式
- 去重:防止重复处理同一条消息(重启、重试)
- 结对检查:在事件到达运行时之前强制执行
[channels.<name>.allowed_users]/ IAM 策略
如果频道未配对或用户无权访问,该事件在运行时看到它之前就会被丢弃。
代理循环
sequenceDiagram
participant CH as Channel
participant RT as Runtime
participant SEC as Security
participant MEM as Memory / history
participant PR as Provider
participant TL as Tool
CH->>RT: process_message(envelope)
Note over RT: resolve memory-inject policy from the turn's TurnOrigin
RT->>MEM: recall(query, session scopes)
MEM-->>RT: entries
Note over RT: render [Memory context] preamble (engine-side)
RT->>PR: chat(system, history, tools)
loop Streaming
PR-->>RT: StreamEvent::TextDelta
RT-->>CH: draft update (if channel supports it)
end
PR-->>RT: StreamEvent::ToolCall(args)
RT->>SEC: evaluate_tool_access(name, args, risk)
alt Blocked
SEC-->>RT: Err(reason)
RT->>PR: chat(..., + tool_error)
else Approval required
SEC->>CH: ask_operator(prompt)
CH-->>SEC: approved / denied
else Allowed
SEC-->>RT: Ok
end
RT->>TL: invoke(args)
TL-->>RT: ToolResult
RT->>MEM: append to turn/session history
RT->>PR: chat(..., + tool_result)
PR-->>RT: StreamEvent::TextDelta (final)
RT-->>CH: reply(final)
RT->>MEM: persist conversation/session history
关键属性:
- 流式传输是端到端的。 提供商会流式传输令牌。如果通道适配器报告
supports_draft_updates(),运行时会在文本到达时就地编辑已发送的消息。Discord、Slack 和 Telegram 支持此功能。 - **工具调用处于流处理中。**模型可以在仍生成文本的同时发出工具调用。运行时会读取流直至完成,在可见文本到达时立即刷新,然后恢复工具调用、进行验证、执行调用、将结果反馈回来,并为下一轮启动新的流。
- **流式完成遵循协议事件。**提供商在收到终止 SSE 事件时即完成成功的流式请求,而不是等待服务器关闭连接。无字节传输的响应正文会在达到提供商的字节空闲超时时失败,而正在进行的生成过程可能持续超过非流式请求超时时间。
- 安全机制会对每次工具调用进行把关。
evaluate_tool_access会查询自治级别、允许/拒绝列表以及路径边界。在Supervised自治模式下,中等风险的调用会进入操作员审批流程。 - Memory 上下文由引擎注入。 在首次 provider 调用之前,turn 引擎会根据该 turn 的
TurnOrigin(谁发起了该 turn)解析注入策略:嵌套子 turn 永不注入,计划性来源(cron、daemon)会注入但排除 conversation-category 条目,而面向用户的来源会注入(当该 turn 没有 session scope 时会排除 conversation 条目)。spawn site 可以对任何来源抑制注入(例如一个带有uses_memory = false的 cron job),而不携带 memory backend 的 turn 会完全跳过它。单一 renderer 会在所有路径上一致地应用时间衰减、相关性过滤、prompt-poisoning 跳过集合和预算上限;memory backend 只负责回答recall,不负责格式化上下文。 - 历史和记忆是分开的。 会话历史保留对话、工具调用和工具结果的连续性。显式的记忆写入会将选定条目持久化到记忆后端。回执以内联方式随对话文本传递,而不是作为单独持久化的工件。有关负载所有权的详细信息,请参阅 Memory and payload lifecycle。
工具收据
成功的工具执行可以接收一个 HMAC-SHA256 收据,该收据会追加到工具结果文本中,并在对话中传回给模型,以证明已签名的结果来自运行时。HMAC 使用一个临时的内存密钥进行加密,并基于 tool_name || args || result || timestamp 计算。收据不会写入单独的磁盘日志,也不会形成链式关联;模型可以回显它们,但在没有密钥的情况下无法伪造新的有效收据。参见 Tool receipts。
出站
出站消息会通过相同的通道适配器返回。支持多消息的适配器(如 Discord、Slack)可以将长回复作为一系列消息进行流式传输;其他适配器(如电子邮件、短信)则在流完成时刷新。
在代码中的位置
- Agent 循环:
crates/zeroclaw-runtime/src/agent/turn/(run_tool_call_loop),入口点位于crates/zeroclaw-runtime/src/agent/loop_.rs(process_message、run) - 内存上下文注入:
crates/zeroclaw-runtime/src/agent/memory_inject.rs(resolve_inject_policy,render_memory_context),基于zeroclaw-api的 ingress 类型中的TurnOrigin进行键控,并由轮次引擎调用 - 工具调用访问检查:
crates/zeroclaw-runtime/src/security/(iam_policy.rsevaluate_tool_access) - 通道编排:
crates/zeroclaw-channels/src/orchestrator/ - 提供方流式传输:
crates/zeroclaw-api/src/model_provider.rs(StreamEvent枚举,从zeroclaw-providers重新导出)、compatible.rs(SSE 解析器)
自 #7415 起,每个传输方式(channels、CLI、cron、gateway WebSocket、RPC/zerocode、ACP,以及内嵌的 Agent API)都运行相同的回合引擎:crates/zeroclaw-runtime/src/agent/turn/ 中的 run_tool_call_loop。流式和内嵌入口点是 agent.rs 中的轻量封装,它们围绕共享循环设置各调用方的参数(去重、迭代上限行为、事件发射)。turn/ 模块每个步骤对应一个文件:
| 文件 | 步骤 |
|---|---|
mod.rs | 编排器:迭代控制、调节参数、引导排空 |
history_window.rs · tool_specs.rs · vision_route.rs | 调用前:历史记录维护、工具规范、视觉路由 |
provider_call.rs · stream_consume.rs · stream_guard.rs | LLM 调用、流式消费、流式传输中的协议保护 |
parse_response.rs · protocol_detect.rs · context_recovery.rs | 响应解释、解析问题检测、溢出恢复 |
approval_gate.rs · call_prep.rs | 工具调用审批与准备(去重、钩子、传送默认值) |
post_exec.rs · results_collect.rs · history_append.rs · max_iter.rs | 结果记录、循环检测、历史追加、迭代上限 |
context.rs · events.rs · knobs.rs · steering.rs · outcome.rs · redact.rs · delivery_defaults.rs | 共享类型:轮次上下文、事件、各调用方参数、引导、结果、凭据清理 |