title, updated, status, tags
| title |
updated |
status |
tags |
| 中间件链 |
2026-04-22 |
active |
| module |
| middleware |
| runtime |
|
中间件链
从 index 导航。关联模块: chat butler memory hands-skills
1. 设计决策
中间件是请求处理的管道,每条聊天消息都经过完整链路。
- WHY 优先级排序 (0-999): 数值越小越先执行。宽范围设计允许在任意位置插入新中间件而无需重新编号。
- WHY 注册顺序 != 执行顺序:
kernel/mod.rs 中 14 次 chain.register() 的代码顺序与运行时顺序无关,chain 按 priority() 升序排列后执行。
- WHY 6 类 14 层: 进化(70-79) -> 路由(80-99) -> 上下文(100-199) -> 能力(200-399) -> 安全(400-599) -> 遥测(600-799),优先级范围即执行阶段。
- WHY Stop/Block/AbortLoop: 细粒度流控 -- Stop 中断 LLM 循环,Block 阻止单次工具调用,AbortLoop 终止整个 Agent 循环。命中后跳过所有后续中间件。
2. 关键文件 + 数据流
核心文件
| 文件 |
职责 |
crates/zclaw-runtime/src/middleware.rs |
AgentMiddleware trait + MiddlewareChain 执行引擎 |
crates/zclaw-runtime/src/middleware/ |
14 个中间件实现 (.rs) |
crates/zclaw-kernel/src/kernel/mod.rs:248-361 |
create_middleware_chain() 注册入口 (14 次 register) |
crates/zclaw-saas/src/main.rs |
SaaS HTTP 中间件注册 (10 层) |
执行流
集成契约
| 方向 |
模块 |
接口 |
触发时机 |
| Called by <- |
kernel |
kernel/mod.rs:create_middleware_chain() |
Kernel 启动 |
| Calls -> |
runtime |
MiddlewareChain::run_before_completion() |
每条聊天请求 |
| Called by <- |
saas |
HTTP relay handler |
SaaS relay 路由 |
| Provides -> |
all |
AgentMiddleware trait |
14 个实现 |
3. 代码逻辑
14 层 Runtime 中间件
| 优先级 |
中间件 |
文件 |
职责 |
注册条件 |
| @78 |
EvolutionMiddleware |
evolution.rs |
推送进化候选项到 system prompt |
始终 |
| @80 |
ButlerRouter |
butler_router.rs |
语义技能路由 + system prompt 增强 + XML fencing |
始终 |
| @100 |
Compaction |
compaction.rs |
超阈值时压缩对话历史 |
compaction_threshold > 0 |
| @150 |
Memory |
memory.rs |
对话后自动提取记忆 + 注入检索结果 |
始终 |
| @180 |
Title |
title.rs |
自动生成会话标题 |
始终 |
| @200 |
SkillIndex |
skill_index.rs |
注入技能索引到 system prompt |
!skill_index.is_empty() |
| @300 |
DanglingTool |
dangling_tool.rs |
修复缺失的工具调用结果 |
始终 |
| @350 |
ToolError |
tool_error.rs |
格式化工具错误供 LLM 恢复 |
始终 |
| @360 |
ToolOutputGuard |
tool_output_guard.rs |
工具输出安全检查 |
始终 |
| @400 |
Guardrail |
guardrail.rs |
shell_exec/file_write/web_fetch 安全规则 |
始终 |
| @500 |
LoopGuard |
loop_guard.rs |
防止工具调用无限循环 |
始终 |
| @550 |
SubagentLimit |
subagent_limit.rs |
限制并发子 agent |
始终 |
| @650 |
TrajectoryRecorder |
trajectory_recorder.rs |
轨迹记录 + 压缩 |
始终 |
| @700 |
TokenCalibration |
token_calibration.rs |
Token 用量校准 |
始终 |
注册顺序 (代码) 与执行顺序 (priority) 不同。Chain 按 priority 升序排列后执行。
10 层 SaaS HTTP 中间件
| 层级 |
中间件 |
职责 |
| 公共路由 |
public_rate_limit_middleware |
20次/分钟/IP |
| 公共+认证 |
api_version_middleware |
API 版本校验 |
| 公共+认证 |
request_id_middleware |
请求 ID 注入 |
| 认证路由 |
rate_limit_middleware |
5次/分钟/IP |
| 认证路由 |
auth_middleware |
JWT 认证 + 权限 |
| 认证路由 |
TimeoutLayer |
请求超时 15s |
| Relay 路由 |
api_version_middleware |
版本校验 |
| Relay 路由 |
request_id_middleware |
请求 ID |
| Relay 路由 |
quota_check_middleware |
配额检查 |
| 全局 |
CORS / 其他 layer |
跨域等 |
不变量
- Priority 升序: 0-999, 数值越小越先执行
- 注册顺序 != 执行顺序; chain 按 priority 运行时排序
- Stop/Block/AbortLoop 立即中断, 不执行后续中间件
核心接口
4. 活跃问题 + 陷阱
活跃问题
- 11/14 中间件无独立测试 (P2): 仅
butler_router(12) / evolution(4) / trajectory_recorder(4) 有测试,共 20 个。其余 11 层依赖集成测试覆盖。
- SkillIndex 条件注册 (长期观察): 无技能时不注册,非 bug 但需关注空技能场景下的行为一致性。
历史陷阱
| 问题 |
根因 |
修复 |
| TrajectoryRecorder 未注册 |
V13-GAP-01: 遗漏 chain.register() 调用 |
已在 @650 注册 |
| Admin 端点 404 而非 403 |
admin_guard_middleware 返回码错误 |
已修复为 403 |
| DataMasking 中间件 |
增加延迟但无实际安全收益 |
04-22 移除 |
5. 变更日志
| 日期 |
变更 |
影响 |
| 04-22 |
DataMasking 中间件移除 |
14->14 层 (替换为无), 减少 1 层无收益处理 |
| 04-22 |
跨会话记忆修复 |
Memory 中间件去重+跨会话注入修复 |
| 04-22 |
Wiki 一致性校准 |
数字与代码验证对齐 |
| 04-21 |
Embedding 接通 |
SkillIndex 路由 TF-IDF->Embedding+LLM fallback |
| 04-15 |
Heartbeat 统一健康系统 |
TrajectoryRecorder 痛点感知增强 |