【全域智能营销实战】10、三大引擎协同工作流:从用户消息到智能决策的完整链路

三大引擎协同工作流:从用户消息到智能决策的完整链路

OpenClaw + Harness + Hermes 三驾马车如何协同工作?一条消息的完整旅程

📑 目录


一、引言:一条消息的旅程

当用户在飞书群里发了一条消息:"帮我分析一下最近一周的营销数据,生成一份报告"------这条消息是如何被系统理解、处理、并最终返回结果的?

这个过程涉及三个引擎的协同工作:

引擎 职责 在链路中的位置
OpenClaw 消息接入与渠道网关 第一站:接收消息,归一化,路由
Harness 安全约束与校验 第二站:权限校验,边界检查,风控
Hermes 智能决策与自进化 第三站:推理决策,工具执行,学习优化

这三个引擎各司其职,形成了一个完整的**"感知→约束→决策→执行→学习→响应"**闭环。

本文将完整拆解一条消息从入站到出站的全链路,展示三大引擎如何协同工作。


二、端到端流程总览

2.1 七步全景图

#mermaid-svg-FDMmGiN0WXdW2Ljn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FDMmGiN0WXdW2Ljn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FDMmGiN0WXdW2Ljn .error-icon{fill:#552222;}#mermaid-svg-FDMmGiN0WXdW2Ljn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FDMmGiN0WXdW2Ljn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FDMmGiN0WXdW2Ljn .marker.cross{stroke:#333333;}#mermaid-svg-FDMmGiN0WXdW2Ljn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FDMmGiN0WXdW2Ljn p{margin:0;}#mermaid-svg-FDMmGiN0WXdW2Ljn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FDMmGiN0WXdW2Ljn .cluster-label text{fill:#333;}#mermaid-svg-FDMmGiN0WXdW2Ljn .cluster-label span{color:#333;}#mermaid-svg-FDMmGiN0WXdW2Ljn .cluster-label span p{background-color:transparent;}#mermaid-svg-FDMmGiN0WXdW2Ljn .label text,#mermaid-svg-FDMmGiN0WXdW2Ljn span{fill:#333;color:#333;}#mermaid-svg-FDMmGiN0WXdW2Ljn .node rect,#mermaid-svg-FDMmGiN0WXdW2Ljn .node circle,#mermaid-svg-FDMmGiN0WXdW2Ljn .node ellipse,#mermaid-svg-FDMmGiN0WXdW2Ljn .node polygon,#mermaid-svg-FDMmGiN0WXdW2Ljn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FDMmGiN0WXdW2Ljn .rough-node .label text,#mermaid-svg-FDMmGiN0WXdW2Ljn .node .label text,#mermaid-svg-FDMmGiN0WXdW2Ljn .image-shape .label,#mermaid-svg-FDMmGiN0WXdW2Ljn .icon-shape .label{text-anchor:middle;}#mermaid-svg-FDMmGiN0WXdW2Ljn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FDMmGiN0WXdW2Ljn .rough-node .label,#mermaid-svg-FDMmGiN0WXdW2Ljn .node .label,#mermaid-svg-FDMmGiN0WXdW2Ljn .image-shape .label,#mermaid-svg-FDMmGiN0WXdW2Ljn .icon-shape .label{text-align:center;}#mermaid-svg-FDMmGiN0WXdW2Ljn .node.clickable{cursor:pointer;}#mermaid-svg-FDMmGiN0WXdW2Ljn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FDMmGiN0WXdW2Ljn .arrowheadPath{fill:#333333;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FDMmGiN0WXdW2Ljn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FDMmGiN0WXdW2Ljn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FDMmGiN0WXdW2Ljn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FDMmGiN0WXdW2Ljn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FDMmGiN0WXdW2Ljn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FDMmGiN0WXdW2Ljn .cluster text{fill:#333;}#mermaid-svg-FDMmGiN0WXdW2Ljn .cluster span{color:#333;}#mermaid-svg-FDMmGiN0WXdW2Ljn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FDMmGiN0WXdW2Ljn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FDMmGiN0WXdW2Ljn rect.text{fill:none;stroke-width:0;}#mermaid-svg-FDMmGiN0WXdW2Ljn .icon-shape,#mermaid-svg-FDMmGiN0WXdW2Ljn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FDMmGiN0WXdW2Ljn .icon-shape p,#mermaid-svg-FDMmGiN0WXdW2Ljn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FDMmGiN0WXdW2Ljn .icon-shape .label rect,#mermaid-svg-FDMmGiN0WXdW2Ljn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FDMmGiN0WXdW2Ljn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FDMmGiN0WXdW2Ljn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FDMmGiN0WXdW2Ljn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 通过
拒绝
阶段七:响应返回
OpenClaw Gateway

结果回传用户
阶段六:自改进
Hermes 学习循环

反馈收集→Skill优化→记忆更新
阶段五:工具执行
Tool Executor

数据查询/API调用/文件操作
阶段四:智能决策
Hermes Agent

System Prompt组装→Agent Loop→工具调用
阶段三:约束校验
Harness 约束层

认知约束·权限约束·流程约束
阶段二:会话管理
Session Manager

获取/创建会话
阶段一:消息接入
OpenClaw Gateway

多渠道统一入站
👤 用户发送消息
🚫 返回拒绝信息

记录审计日志
✅ 用户收到回复

2.2 各阶段职责速览

阶段 引擎 核心职责 关键产出
① 消息接入 OpenClaw 多渠道消息接收、验签、归一化 UnifiedMessage
② 会话管理 Session Manager 获取/创建会话,加载上下文 SessionContext
③ 约束校验 Harness 权限校验、边界检查、风控 ConstraintResult
④ 智能决策 Hermes System Prompt 组装、Agent Loop 决策结果
⑤ 工具执行 Tool Executor 数据查询、API 调用、文件操作 执行结果
⑥ 自改进 Hermes 反馈收集、Skill 优化、记忆更新 学习结果
⑦ 响应返回 OpenClaw 结果格式化、渠道适配、推送 用户响应

三、阶段一:消息接入(OpenClaw)

3.1 多渠道统一入站

OpenClaw Gateway 作为消息接入层,负责接收来自多个渠道的 Webhook 回调。
#mermaid-svg-d6sBHRDSiD9oL3hS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-d6sBHRDSiD9oL3hS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-d6sBHRDSiD9oL3hS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-d6sBHRDSiD9oL3hS .error-icon{fill:#552222;}#mermaid-svg-d6sBHRDSiD9oL3hS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-d6sBHRDSiD9oL3hS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-d6sBHRDSiD9oL3hS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-d6sBHRDSiD9oL3hS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-d6sBHRDSiD9oL3hS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-d6sBHRDSiD9oL3hS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-d6sBHRDSiD9oL3hS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-d6sBHRDSiD9oL3hS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-d6sBHRDSiD9oL3hS .marker.cross{stroke:#333333;}#mermaid-svg-d6sBHRDSiD9oL3hS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-d6sBHRDSiD9oL3hS p{margin:0;}#mermaid-svg-d6sBHRDSiD9oL3hS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-d6sBHRDSiD9oL3hS .cluster-label text{fill:#333;}#mermaid-svg-d6sBHRDSiD9oL3hS .cluster-label span{color:#333;}#mermaid-svg-d6sBHRDSiD9oL3hS .cluster-label span p{background-color:transparent;}#mermaid-svg-d6sBHRDSiD9oL3hS .label text,#mermaid-svg-d6sBHRDSiD9oL3hS span{fill:#333;color:#333;}#mermaid-svg-d6sBHRDSiD9oL3hS .node rect,#mermaid-svg-d6sBHRDSiD9oL3hS .node circle,#mermaid-svg-d6sBHRDSiD9oL3hS .node ellipse,#mermaid-svg-d6sBHRDSiD9oL3hS .node polygon,#mermaid-svg-d6sBHRDSiD9oL3hS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-d6sBHRDSiD9oL3hS .rough-node .label text,#mermaid-svg-d6sBHRDSiD9oL3hS .node .label text,#mermaid-svg-d6sBHRDSiD9oL3hS .image-shape .label,#mermaid-svg-d6sBHRDSiD9oL3hS .icon-shape .label{text-anchor:middle;}#mermaid-svg-d6sBHRDSiD9oL3hS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-d6sBHRDSiD9oL3hS .rough-node .label,#mermaid-svg-d6sBHRDSiD9oL3hS .node .label,#mermaid-svg-d6sBHRDSiD9oL3hS .image-shape .label,#mermaid-svg-d6sBHRDSiD9oL3hS .icon-shape .label{text-align:center;}#mermaid-svg-d6sBHRDSiD9oL3hS .node.clickable{cursor:pointer;}#mermaid-svg-d6sBHRDSiD9oL3hS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-d6sBHRDSiD9oL3hS .arrowheadPath{fill:#333333;}#mermaid-svg-d6sBHRDSiD9oL3hS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-d6sBHRDSiD9oL3hS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-d6sBHRDSiD9oL3hS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-d6sBHRDSiD9oL3hS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-d6sBHRDSiD9oL3hS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-d6sBHRDSiD9oL3hS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-d6sBHRDSiD9oL3hS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-d6sBHRDSiD9oL3hS .cluster text{fill:#333;}#mermaid-svg-d6sBHRDSiD9oL3hS .cluster span{color:#333;}#mermaid-svg-d6sBHRDSiD9oL3hS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-d6sBHRDSiD9oL3hS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-d6sBHRDSiD9oL3hS rect.text{fill:none;stroke-width:0;}#mermaid-svg-d6sBHRDSiD9oL3hS .icon-shape,#mermaid-svg-d6sBHRDSiD9oL3hS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-d6sBHRDSiD9oL3hS .icon-shape p,#mermaid-svg-d6sBHRDSiD9oL3hS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-d6sBHRDSiD9oL3hS .icon-shape .label rect,#mermaid-svg-d6sBHRDSiD9oL3hS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-d6sBHRDSiD9oL3hS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-d6sBHRDSiD9oL3hS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-d6sBHRDSiD9oL3hS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输出
OpenClaw Gateway
消息渠道
飞书
钉钉
企微
Telegram
Webhook Receiver
Signature Verifier
Message Normalizer
UnifiedMessage

统一消息格式

3.2 消息归一化与路由

java 复制代码
@Component
@Slf4j
public class MessageRouter {
    
    public RoutingResult route(UnifiedMessage message) {
        // 1. 检查是否为系统命令
        if (isSystemCommand(message.getContent())) {
            return RoutingResult.systemCommand(message);
        }
        
        // 2. 检查是否为斜杠命令(快捷调用 Skill)
        if (isSlashCommand(message.getContent())) {
            return RoutingResult.slashCommand(message);
        }
        
        // 3. 普通对话:路由到 Agent
        return RoutingResult.agent(message);
    }
}

四、阶段二:会话管理(Session Manager)

会话管理负责获取或创建会话,加载用户的上下文信息。
#mermaid-svg-xjJmNWnRSMIVkDpI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xjJmNWnRSMIVkDpI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xjJmNWnRSMIVkDpI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xjJmNWnRSMIVkDpI .error-icon{fill:#552222;}#mermaid-svg-xjJmNWnRSMIVkDpI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xjJmNWnRSMIVkDpI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xjJmNWnRSMIVkDpI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xjJmNWnRSMIVkDpI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xjJmNWnRSMIVkDpI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xjJmNWnRSMIVkDpI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xjJmNWnRSMIVkDpI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xjJmNWnRSMIVkDpI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xjJmNWnRSMIVkDpI .marker.cross{stroke:#333333;}#mermaid-svg-xjJmNWnRSMIVkDpI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xjJmNWnRSMIVkDpI p{margin:0;}#mermaid-svg-xjJmNWnRSMIVkDpI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xjJmNWnRSMIVkDpI .cluster-label text{fill:#333;}#mermaid-svg-xjJmNWnRSMIVkDpI .cluster-label span{color:#333;}#mermaid-svg-xjJmNWnRSMIVkDpI .cluster-label span p{background-color:transparent;}#mermaid-svg-xjJmNWnRSMIVkDpI .label text,#mermaid-svg-xjJmNWnRSMIVkDpI span{fill:#333;color:#333;}#mermaid-svg-xjJmNWnRSMIVkDpI .node rect,#mermaid-svg-xjJmNWnRSMIVkDpI .node circle,#mermaid-svg-xjJmNWnRSMIVkDpI .node ellipse,#mermaid-svg-xjJmNWnRSMIVkDpI .node polygon,#mermaid-svg-xjJmNWnRSMIVkDpI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xjJmNWnRSMIVkDpI .rough-node .label text,#mermaid-svg-xjJmNWnRSMIVkDpI .node .label text,#mermaid-svg-xjJmNWnRSMIVkDpI .image-shape .label,#mermaid-svg-xjJmNWnRSMIVkDpI .icon-shape .label{text-anchor:middle;}#mermaid-svg-xjJmNWnRSMIVkDpI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xjJmNWnRSMIVkDpI .rough-node .label,#mermaid-svg-xjJmNWnRSMIVkDpI .node .label,#mermaid-svg-xjJmNWnRSMIVkDpI .image-shape .label,#mermaid-svg-xjJmNWnRSMIVkDpI .icon-shape .label{text-align:center;}#mermaid-svg-xjJmNWnRSMIVkDpI .node.clickable{cursor:pointer;}#mermaid-svg-xjJmNWnRSMIVkDpI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xjJmNWnRSMIVkDpI .arrowheadPath{fill:#333333;}#mermaid-svg-xjJmNWnRSMIVkDpI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xjJmNWnRSMIVkDpI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xjJmNWnRSMIVkDpI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xjJmNWnRSMIVkDpI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xjJmNWnRSMIVkDpI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xjJmNWnRSMIVkDpI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xjJmNWnRSMIVkDpI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xjJmNWnRSMIVkDpI .cluster text{fill:#333;}#mermaid-svg-xjJmNWnRSMIVkDpI .cluster span{color:#333;}#mermaid-svg-xjJmNWnRSMIVkDpI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xjJmNWnRSMIVkDpI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xjJmNWnRSMIVkDpI rect.text{fill:none;stroke-width:0;}#mermaid-svg-xjJmNWnRSMIVkDpI .icon-shape,#mermaid-svg-xjJmNWnRSMIVkDpI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xjJmNWnRSMIVkDpI .icon-shape p,#mermaid-svg-xjJmNWnRSMIVkDpI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xjJmNWnRSMIVkDpI .icon-shape .label rect,#mermaid-svg-xjJmNWnRSMIVkDpI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xjJmNWnRSMIVkDpI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xjJmNWnRSMIVkDpI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xjJmNWnRSMIVkDpI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

UnifiedMessage
SessionManager.getOrCreate
是否有

已有会话?
加载会话上下文

对话历史·记忆·偏好
创建新会话

生成 Session ID
SessionContext
进入下一阶段

java 复制代码
@Service
@Slf4j
public class SessionManager {
    
    private static final String SESSION_KEY_PREFIX = "unimdp:session:";
    
    public SessionContext getOrCreate(UnifiedMessage message) {
        // 1. 优先使用已有 session_id
        if (message.getSessionId() != null) {
            SessionContext context = get(message.getSessionId());
            if (context != null) {
                context.setLastActiveAt(System.currentTimeMillis());
                update(context);
                return context;
            }
        }
        
        // 2. 查找同一用户的活跃会话
        List<SessionContext> userSessions = findActiveByUser(message.getUnifiedUserId());
        if (!userSessions.isEmpty()) {
            SessionContext latest = userSessions.get(0);
            latest.setLastActiveAt(System.currentTimeMillis());
            update(latest);
            return latest;
        }
        
        // 3. 创建新会话
        return create(message);
    }
}

SessionContext 包含的核心信息

字段 说明
sessionId 会话唯一标识
unifiedUserId 统一用户 ID(OneID)
channelType 消息渠道类型
status 会话状态(INIT/ACTIVE/PAUSED/CLOSED)
history 对话历史(压缩后)
memory 用户记忆快照
context 扩展上下文

五、阶段三:约束校验(Harness)

约束校验是 Harness 的核心职责,在 Agent 决策之前进行安全检查。

5.1 三层约束校验流程

#mermaid-svg-j4jdXuClXv9abucK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-j4jdXuClXv9abucK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-j4jdXuClXv9abucK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-j4jdXuClXv9abucK .error-icon{fill:#552222;}#mermaid-svg-j4jdXuClXv9abucK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-j4jdXuClXv9abucK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-j4jdXuClXv9abucK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-j4jdXuClXv9abucK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-j4jdXuClXv9abucK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-j4jdXuClXv9abucK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-j4jdXuClXv9abucK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-j4jdXuClXv9abucK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-j4jdXuClXv9abucK .marker.cross{stroke:#333333;}#mermaid-svg-j4jdXuClXv9abucK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-j4jdXuClXv9abucK p{margin:0;}#mermaid-svg-j4jdXuClXv9abucK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-j4jdXuClXv9abucK .cluster-label text{fill:#333;}#mermaid-svg-j4jdXuClXv9abucK .cluster-label span{color:#333;}#mermaid-svg-j4jdXuClXv9abucK .cluster-label span p{background-color:transparent;}#mermaid-svg-j4jdXuClXv9abucK .label text,#mermaid-svg-j4jdXuClXv9abucK span{fill:#333;color:#333;}#mermaid-svg-j4jdXuClXv9abucK .node rect,#mermaid-svg-j4jdXuClXv9abucK .node circle,#mermaid-svg-j4jdXuClXv9abucK .node ellipse,#mermaid-svg-j4jdXuClXv9abucK .node polygon,#mermaid-svg-j4jdXuClXv9abucK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-j4jdXuClXv9abucK .rough-node .label text,#mermaid-svg-j4jdXuClXv9abucK .node .label text,#mermaid-svg-j4jdXuClXv9abucK .image-shape .label,#mermaid-svg-j4jdXuClXv9abucK .icon-shape .label{text-anchor:middle;}#mermaid-svg-j4jdXuClXv9abucK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-j4jdXuClXv9abucK .rough-node .label,#mermaid-svg-j4jdXuClXv9abucK .node .label,#mermaid-svg-j4jdXuClXv9abucK .image-shape .label,#mermaid-svg-j4jdXuClXv9abucK .icon-shape .label{text-align:center;}#mermaid-svg-j4jdXuClXv9abucK .node.clickable{cursor:pointer;}#mermaid-svg-j4jdXuClXv9abucK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-j4jdXuClXv9abucK .arrowheadPath{fill:#333333;}#mermaid-svg-j4jdXuClXv9abucK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-j4jdXuClXv9abucK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-j4jdXuClXv9abucK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j4jdXuClXv9abucK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-j4jdXuClXv9abucK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j4jdXuClXv9abucK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-j4jdXuClXv9abucK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-j4jdXuClXv9abucK .cluster text{fill:#333;}#mermaid-svg-j4jdXuClXv9abucK .cluster span{color:#333;}#mermaid-svg-j4jdXuClXv9abucK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-j4jdXuClXv9abucK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-j4jdXuClXv9abucK rect.text{fill:none;stroke-width:0;}#mermaid-svg-j4jdXuClXv9abucK .icon-shape,#mermaid-svg-j4jdXuClXv9abucK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j4jdXuClXv9abucK .icon-shape p,#mermaid-svg-j4jdXuClXv9abucK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-j4jdXuClXv9abucK .icon-shape .label rect,#mermaid-svg-j4jdXuClXv9abucK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j4jdXuClXv9abucK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-j4jdXuClXv9abucK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-j4jdXuClXv9abucK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 通过
拒绝
警告
Harness 约束层
认知约束

行为准则检查
权限约束

工具白名单/黑名单
流程约束

执行流程校验
SessionContext + UnifiedMessage
校验结果
进入决策阶段
🚫 拒绝执行

记录审计日志
⚠️ 记录警告

继续执行

5.2 约束校验代码实现

java 复制代码
package com.unimdp.orchestration;

@Component
@Slf4j
public class HarnessConstraintService {
    
    @Autowired
    private RuleEngine ruleEngine;
    
    @Autowired
    private AuditService auditService;
    
    public ConstraintResult validate(ToolCallContext context) {
        // 1. 执行认知约束检查
        ConstraintResult cognitive = checkCognitiveConstraint(context);
        if (!cognitive.isPassed()) {
            auditService.logConstraintBlock(context, cognitive);
            return cognitive;
        }
        
        // 2. 执行权限约束检查
        ConstraintResult permission = checkPermissionConstraint(context);
        if (!permission.isPassed()) {
            auditService.logConstraintBlock(context, permission);
            return permission;
        }
        
        // 3. 执行流程约束检查
        ConstraintResult process = checkProcessConstraint(context);
        if (!process.isPassed()) {
            auditService.logConstraintBlock(context, process);
            return process;
        }
        
        return ConstraintResult.pass();
    }
}

六、阶段四:智能决策(Hermes)

6.1 System Prompt 三层组装

#mermaid-svg-oChAFFgP6U0mp64X{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oChAFFgP6U0mp64X .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oChAFFgP6U0mp64X .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oChAFFgP6U0mp64X .error-icon{fill:#552222;}#mermaid-svg-oChAFFgP6U0mp64X .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oChAFFgP6U0mp64X .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oChAFFgP6U0mp64X .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oChAFFgP6U0mp64X .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oChAFFgP6U0mp64X .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oChAFFgP6U0mp64X .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oChAFFgP6U0mp64X .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oChAFFgP6U0mp64X .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oChAFFgP6U0mp64X .marker.cross{stroke:#333333;}#mermaid-svg-oChAFFgP6U0mp64X svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oChAFFgP6U0mp64X p{margin:0;}#mermaid-svg-oChAFFgP6U0mp64X .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-oChAFFgP6U0mp64X .cluster-label text{fill:#333;}#mermaid-svg-oChAFFgP6U0mp64X .cluster-label span{color:#333;}#mermaid-svg-oChAFFgP6U0mp64X .cluster-label span p{background-color:transparent;}#mermaid-svg-oChAFFgP6U0mp64X .label text,#mermaid-svg-oChAFFgP6U0mp64X span{fill:#333;color:#333;}#mermaid-svg-oChAFFgP6U0mp64X .node rect,#mermaid-svg-oChAFFgP6U0mp64X .node circle,#mermaid-svg-oChAFFgP6U0mp64X .node ellipse,#mermaid-svg-oChAFFgP6U0mp64X .node polygon,#mermaid-svg-oChAFFgP6U0mp64X .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oChAFFgP6U0mp64X .rough-node .label text,#mermaid-svg-oChAFFgP6U0mp64X .node .label text,#mermaid-svg-oChAFFgP6U0mp64X .image-shape .label,#mermaid-svg-oChAFFgP6U0mp64X .icon-shape .label{text-anchor:middle;}#mermaid-svg-oChAFFgP6U0mp64X .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-oChAFFgP6U0mp64X .rough-node .label,#mermaid-svg-oChAFFgP6U0mp64X .node .label,#mermaid-svg-oChAFFgP6U0mp64X .image-shape .label,#mermaid-svg-oChAFFgP6U0mp64X .icon-shape .label{text-align:center;}#mermaid-svg-oChAFFgP6U0mp64X .node.clickable{cursor:pointer;}#mermaid-svg-oChAFFgP6U0mp64X .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-oChAFFgP6U0mp64X .arrowheadPath{fill:#333333;}#mermaid-svg-oChAFFgP6U0mp64X .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oChAFFgP6U0mp64X .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oChAFFgP6U0mp64X .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oChAFFgP6U0mp64X .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-oChAFFgP6U0mp64X .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oChAFFgP6U0mp64X .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-oChAFFgP6U0mp64X .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oChAFFgP6U0mp64X .cluster text{fill:#333;}#mermaid-svg-oChAFFgP6U0mp64X .cluster span{color:#333;}#mermaid-svg-oChAFFgP6U0mp64X div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oChAFFgP6U0mp64X .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oChAFFgP6U0mp64X rect.text{fill:none;stroke-width:0;}#mermaid-svg-oChAFFgP6U0mp64X .icon-shape,#mermaid-svg-oChAFFgP6U0mp64X .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oChAFFgP6U0mp64X .icon-shape p,#mermaid-svg-oChAFFgP6U0mp64X .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-oChAFFgP6U0mp64X .icon-shape .label rect,#mermaid-svg-oChAFFgP6U0mp64X .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oChAFFgP6U0mp64X .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oChAFFgP6U0mp64X .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oChAFFgP6U0mp64X :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 🟥 Volatile 易变层
记忆快照
用户画像
时间戳/会话信息
🟨 Context 上下文层
项目规则文件
调用方传入的系统消息
🟦 Stable 稳定层
Agent 身份定义
工具使用指导
技能索引
最终 System Prompt

6.2 Agent Loop 执行

#mermaid-svg-ha3F82vjk4e5e7jw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ha3F82vjk4e5e7jw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ha3F82vjk4e5e7jw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ha3F82vjk4e5e7jw .error-icon{fill:#552222;}#mermaid-svg-ha3F82vjk4e5e7jw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ha3F82vjk4e5e7jw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ha3F82vjk4e5e7jw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ha3F82vjk4e5e7jw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ha3F82vjk4e5e7jw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ha3F82vjk4e5e7jw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ha3F82vjk4e5e7jw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ha3F82vjk4e5e7jw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ha3F82vjk4e5e7jw .marker.cross{stroke:#333333;}#mermaid-svg-ha3F82vjk4e5e7jw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ha3F82vjk4e5e7jw p{margin:0;}#mermaid-svg-ha3F82vjk4e5e7jw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ha3F82vjk4e5e7jw .cluster-label text{fill:#333;}#mermaid-svg-ha3F82vjk4e5e7jw .cluster-label span{color:#333;}#mermaid-svg-ha3F82vjk4e5e7jw .cluster-label span p{background-color:transparent;}#mermaid-svg-ha3F82vjk4e5e7jw .label text,#mermaid-svg-ha3F82vjk4e5e7jw span{fill:#333;color:#333;}#mermaid-svg-ha3F82vjk4e5e7jw .node rect,#mermaid-svg-ha3F82vjk4e5e7jw .node circle,#mermaid-svg-ha3F82vjk4e5e7jw .node ellipse,#mermaid-svg-ha3F82vjk4e5e7jw .node polygon,#mermaid-svg-ha3F82vjk4e5e7jw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ha3F82vjk4e5e7jw .rough-node .label text,#mermaid-svg-ha3F82vjk4e5e7jw .node .label text,#mermaid-svg-ha3F82vjk4e5e7jw .image-shape .label,#mermaid-svg-ha3F82vjk4e5e7jw .icon-shape .label{text-anchor:middle;}#mermaid-svg-ha3F82vjk4e5e7jw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ha3F82vjk4e5e7jw .rough-node .label,#mermaid-svg-ha3F82vjk4e5e7jw .node .label,#mermaid-svg-ha3F82vjk4e5e7jw .image-shape .label,#mermaid-svg-ha3F82vjk4e5e7jw .icon-shape .label{text-align:center;}#mermaid-svg-ha3F82vjk4e5e7jw .node.clickable{cursor:pointer;}#mermaid-svg-ha3F82vjk4e5e7jw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ha3F82vjk4e5e7jw .arrowheadPath{fill:#333333;}#mermaid-svg-ha3F82vjk4e5e7jw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ha3F82vjk4e5e7jw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ha3F82vjk4e5e7jw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ha3F82vjk4e5e7jw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ha3F82vjk4e5e7jw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ha3F82vjk4e5e7jw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ha3F82vjk4e5e7jw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ha3F82vjk4e5e7jw .cluster text{fill:#333;}#mermaid-svg-ha3F82vjk4e5e7jw .cluster span{color:#333;}#mermaid-svg-ha3F82vjk4e5e7jw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ha3F82vjk4e5e7jw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ha3F82vjk4e5e7jw rect.text{fill:none;stroke-width:0;}#mermaid-svg-ha3F82vjk4e5e7jw .icon-shape,#mermaid-svg-ha3F82vjk4e5e7jw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ha3F82vjk4e5e7jw .icon-shape p,#mermaid-svg-ha3F82vjk4e5e7jw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ha3F82vjk4e5e7jw .icon-shape .label rect,#mermaid-svg-ha3F82vjk4e5e7jw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ha3F82vjk4e5e7jw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ha3F82vjk4e5e7jw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ha3F82vjk4e5e7jw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 工具调用
最终答案
上下文超限
开始
构建 System Prompt
调用 LLM
响应类型
执行工具
追加工具结果到历史
返回结果
触发上下文压缩
结束

java 复制代码
package com.unimdp.orchestration;

@Service
@Slf4j
public class HermesDecisionService {
    
    @Autowired
    private ChatClient chatClient;
    
    @Autowired
    private SystemPromptBuilder promptBuilder;
    
    @Autowired
    private ToolRegistry toolRegistry;
    
    public DecisionResult decide(SessionContext context, UnifiedMessage message) {
        // 1. 构建 System Prompt
        String systemPrompt = promptBuilder.build(
            context.getSessionId(),
            context.getUnifiedUserId(),
            message.getContent(),
            context.getContext()
        );
        
        // 2. 执行 Agent Loop
        String response = chatClient.prompt()
            .system(systemPrompt)
            .user(message.getContent())
            .advisors(new ToolCallingAdvisor(toolRegistry))
            .advisors(new LoggingAdvisor())
            .advisors(new ValidationAdvisor())
            .call()
            .content();
        
        // 3. 返回决策结果
        return DecisionResult.builder()
            .content(response)
            .toolCalls(toolRegistry.getExecutedCalls())
            .tokenUsage(chatClient.getLastTokenUsage())
            .build();
    }
}

6.3 工具调用执行流程

#mermaid-svg-YYXcA1rvZyWqsXyo{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YYXcA1rvZyWqsXyo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YYXcA1rvZyWqsXyo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YYXcA1rvZyWqsXyo .error-icon{fill:#552222;}#mermaid-svg-YYXcA1rvZyWqsXyo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YYXcA1rvZyWqsXyo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YYXcA1rvZyWqsXyo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YYXcA1rvZyWqsXyo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YYXcA1rvZyWqsXyo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YYXcA1rvZyWqsXyo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YYXcA1rvZyWqsXyo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YYXcA1rvZyWqsXyo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YYXcA1rvZyWqsXyo .marker.cross{stroke:#333333;}#mermaid-svg-YYXcA1rvZyWqsXyo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YYXcA1rvZyWqsXyo p{margin:0;}#mermaid-svg-YYXcA1rvZyWqsXyo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YYXcA1rvZyWqsXyo .cluster-label text{fill:#333;}#mermaid-svg-YYXcA1rvZyWqsXyo .cluster-label span{color:#333;}#mermaid-svg-YYXcA1rvZyWqsXyo .cluster-label span p{background-color:transparent;}#mermaid-svg-YYXcA1rvZyWqsXyo .label text,#mermaid-svg-YYXcA1rvZyWqsXyo span{fill:#333;color:#333;}#mermaid-svg-YYXcA1rvZyWqsXyo .node rect,#mermaid-svg-YYXcA1rvZyWqsXyo .node circle,#mermaid-svg-YYXcA1rvZyWqsXyo .node ellipse,#mermaid-svg-YYXcA1rvZyWqsXyo .node polygon,#mermaid-svg-YYXcA1rvZyWqsXyo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YYXcA1rvZyWqsXyo .rough-node .label text,#mermaid-svg-YYXcA1rvZyWqsXyo .node .label text,#mermaid-svg-YYXcA1rvZyWqsXyo .image-shape .label,#mermaid-svg-YYXcA1rvZyWqsXyo .icon-shape .label{text-anchor:middle;}#mermaid-svg-YYXcA1rvZyWqsXyo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YYXcA1rvZyWqsXyo .rough-node .label,#mermaid-svg-YYXcA1rvZyWqsXyo .node .label,#mermaid-svg-YYXcA1rvZyWqsXyo .image-shape .label,#mermaid-svg-YYXcA1rvZyWqsXyo .icon-shape .label{text-align:center;}#mermaid-svg-YYXcA1rvZyWqsXyo .node.clickable{cursor:pointer;}#mermaid-svg-YYXcA1rvZyWqsXyo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YYXcA1rvZyWqsXyo .arrowheadPath{fill:#333333;}#mermaid-svg-YYXcA1rvZyWqsXyo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YYXcA1rvZyWqsXyo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YYXcA1rvZyWqsXyo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YYXcA1rvZyWqsXyo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YYXcA1rvZyWqsXyo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YYXcA1rvZyWqsXyo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YYXcA1rvZyWqsXyo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YYXcA1rvZyWqsXyo .cluster text{fill:#333;}#mermaid-svg-YYXcA1rvZyWqsXyo .cluster span{color:#333;}#mermaid-svg-YYXcA1rvZyWqsXyo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YYXcA1rvZyWqsXyo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YYXcA1rvZyWqsXyo rect.text{fill:none;stroke-width:0;}#mermaid-svg-YYXcA1rvZyWqsXyo .icon-shape,#mermaid-svg-YYXcA1rvZyWqsXyo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YYXcA1rvZyWqsXyo .icon-shape p,#mermaid-svg-YYXcA1rvZyWqsXyo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YYXcA1rvZyWqsXyo .icon-shape .label rect,#mermaid-svg-YYXcA1rvZyWqsXyo .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YYXcA1rvZyWqsXyo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YYXcA1rvZyWqsXyo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YYXcA1rvZyWqsXyo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 工具执行层
数据查询工具

查询营销数据
内容生成工具

生成报告内容
消息推送工具

推送结果
Agent 决策
执行结果


七、阶段五:自改进(Hermes 学习循环)

任务执行完成后,Hermes 的学习循环会评估是否需要将本次经验沉淀为 Skill。

7.1 学习触发条件

#mermaid-svg-8qLqPNfpyLggM2Kj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8qLqPNfpyLggM2Kj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8qLqPNfpyLggM2Kj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8qLqPNfpyLggM2Kj .error-icon{fill:#552222;}#mermaid-svg-8qLqPNfpyLggM2Kj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8qLqPNfpyLggM2Kj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8qLqPNfpyLggM2Kj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8qLqPNfpyLggM2Kj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8qLqPNfpyLggM2Kj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8qLqPNfpyLggM2Kj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8qLqPNfpyLggM2Kj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8qLqPNfpyLggM2Kj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8qLqPNfpyLggM2Kj .marker.cross{stroke:#333333;}#mermaid-svg-8qLqPNfpyLggM2Kj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8qLqPNfpyLggM2Kj p{margin:0;}#mermaid-svg-8qLqPNfpyLggM2Kj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8qLqPNfpyLggM2Kj .cluster-label text{fill:#333;}#mermaid-svg-8qLqPNfpyLggM2Kj .cluster-label span{color:#333;}#mermaid-svg-8qLqPNfpyLggM2Kj .cluster-label span p{background-color:transparent;}#mermaid-svg-8qLqPNfpyLggM2Kj .label text,#mermaid-svg-8qLqPNfpyLggM2Kj span{fill:#333;color:#333;}#mermaid-svg-8qLqPNfpyLggM2Kj .node rect,#mermaid-svg-8qLqPNfpyLggM2Kj .node circle,#mermaid-svg-8qLqPNfpyLggM2Kj .node ellipse,#mermaid-svg-8qLqPNfpyLggM2Kj .node polygon,#mermaid-svg-8qLqPNfpyLggM2Kj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8qLqPNfpyLggM2Kj .rough-node .label text,#mermaid-svg-8qLqPNfpyLggM2Kj .node .label text,#mermaid-svg-8qLqPNfpyLggM2Kj .image-shape .label,#mermaid-svg-8qLqPNfpyLggM2Kj .icon-shape .label{text-anchor:middle;}#mermaid-svg-8qLqPNfpyLggM2Kj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8qLqPNfpyLggM2Kj .rough-node .label,#mermaid-svg-8qLqPNfpyLggM2Kj .node .label,#mermaid-svg-8qLqPNfpyLggM2Kj .image-shape .label,#mermaid-svg-8qLqPNfpyLggM2Kj .icon-shape .label{text-align:center;}#mermaid-svg-8qLqPNfpyLggM2Kj .node.clickable{cursor:pointer;}#mermaid-svg-8qLqPNfpyLggM2Kj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8qLqPNfpyLggM2Kj .arrowheadPath{fill:#333333;}#mermaid-svg-8qLqPNfpyLggM2Kj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8qLqPNfpyLggM2Kj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8qLqPNfpyLggM2Kj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8qLqPNfpyLggM2Kj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8qLqPNfpyLggM2Kj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8qLqPNfpyLggM2Kj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8qLqPNfpyLggM2Kj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8qLqPNfpyLggM2Kj .cluster text{fill:#333;}#mermaid-svg-8qLqPNfpyLggM2Kj .cluster span{color:#333;}#mermaid-svg-8qLqPNfpyLggM2Kj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8qLqPNfpyLggM2Kj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8qLqPNfpyLggM2Kj rect.text{fill:none;stroke-width:0;}#mermaid-svg-8qLqPNfpyLggM2Kj .icon-shape,#mermaid-svg-8qLqPNfpyLggM2Kj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8qLqPNfpyLggM2Kj .icon-shape p,#mermaid-svg-8qLqPNfpyLggM2Kj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8qLqPNfpyLggM2Kj .icon-shape .label rect,#mermaid-svg-8qLqPNfpyLggM2Kj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8qLqPNfpyLggM2Kj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8qLqPNfpyLggM2Kj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8qLqPNfpyLggM2Kj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 工具调用 >= 5 次
出现错误并修复
用户纠正反馈
不满足条件
学习循环
分析执行轨迹
提取可复用模式
生成 SKILL.md
保存到数据库和文件系统
任务完成
评估是否

值得学习
✅ 触发学习
✅ 触发学习
✅ 触发学习
⏭️ 跳过学习
更新记忆

7.2 学习循环代码实现

java 复制代码
package com.unimdp.orchestration;

@Component
@Slf4j
public class LearningService {
    
    @Autowired
    private HermesLearningClient learningClient;
    
    @Autowired
    private SkillRepository skillRepository;
    
    public LearningResult triggerLearning(Task task) {
        // 1. 判断是否满足学习条件
        if (!shouldLearn(task)) {
            return LearningResult.skip("Tool calls count < 5");
        }
        
        // 2. 调用 Hermes 学习循环
        LearningRequest request = LearningRequest.builder()
            .sessionId(task.getSessionId())
            .taskId(task.getTaskId())
            .executionTrace(task.getTrace())
            .build();
        
        LearningResponse response = learningClient.triggerLearning(request);
        
        // 3. 保存生成的 Skill
        if (response.isSkillCreated()) {
            SkillEntity skill = SkillEntity.builder()
                .unifiedUserId(task.getUnifiedUserId())
                .name(response.getSkillName())
                .description(response.getSkillDescription())
                .triggerKeywords(response.getTriggerKeywords())
                .actionSteps(response.getActionSteps())
                .examples(response.getExamples())
                .source("auto_generated")
                .status("active")
                .build();
            
            skillRepository.save(skill);
            
            // 4. 同步到文件系统
            skillFileSyncService.syncToFileSystem(skill);
            
            log.info("✅ Skill created: {}", skill.getName());
            return LearningResult.success(skill);
        }
        
        return LearningResult.noChange();
    }
}

八、阶段六:响应返回(OpenClaw)

决策结果通过 OpenClaw Gateway 回传给用户。
#mermaid-svg-fKn1UWLqMs2y1hKP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fKn1UWLqMs2y1hKP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fKn1UWLqMs2y1hKP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fKn1UWLqMs2y1hKP .error-icon{fill:#552222;}#mermaid-svg-fKn1UWLqMs2y1hKP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fKn1UWLqMs2y1hKP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fKn1UWLqMs2y1hKP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fKn1UWLqMs2y1hKP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fKn1UWLqMs2y1hKP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fKn1UWLqMs2y1hKP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fKn1UWLqMs2y1hKP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fKn1UWLqMs2y1hKP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fKn1UWLqMs2y1hKP .marker.cross{stroke:#333333;}#mermaid-svg-fKn1UWLqMs2y1hKP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fKn1UWLqMs2y1hKP p{margin:0;}#mermaid-svg-fKn1UWLqMs2y1hKP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fKn1UWLqMs2y1hKP .cluster-label text{fill:#333;}#mermaid-svg-fKn1UWLqMs2y1hKP .cluster-label span{color:#333;}#mermaid-svg-fKn1UWLqMs2y1hKP .cluster-label span p{background-color:transparent;}#mermaid-svg-fKn1UWLqMs2y1hKP .label text,#mermaid-svg-fKn1UWLqMs2y1hKP span{fill:#333;color:#333;}#mermaid-svg-fKn1UWLqMs2y1hKP .node rect,#mermaid-svg-fKn1UWLqMs2y1hKP .node circle,#mermaid-svg-fKn1UWLqMs2y1hKP .node ellipse,#mermaid-svg-fKn1UWLqMs2y1hKP .node polygon,#mermaid-svg-fKn1UWLqMs2y1hKP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fKn1UWLqMs2y1hKP .rough-node .label text,#mermaid-svg-fKn1UWLqMs2y1hKP .node .label text,#mermaid-svg-fKn1UWLqMs2y1hKP .image-shape .label,#mermaid-svg-fKn1UWLqMs2y1hKP .icon-shape .label{text-anchor:middle;}#mermaid-svg-fKn1UWLqMs2y1hKP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fKn1UWLqMs2y1hKP .rough-node .label,#mermaid-svg-fKn1UWLqMs2y1hKP .node .label,#mermaid-svg-fKn1UWLqMs2y1hKP .image-shape .label,#mermaid-svg-fKn1UWLqMs2y1hKP .icon-shape .label{text-align:center;}#mermaid-svg-fKn1UWLqMs2y1hKP .node.clickable{cursor:pointer;}#mermaid-svg-fKn1UWLqMs2y1hKP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fKn1UWLqMs2y1hKP .arrowheadPath{fill:#333333;}#mermaid-svg-fKn1UWLqMs2y1hKP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fKn1UWLqMs2y1hKP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fKn1UWLqMs2y1hKP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fKn1UWLqMs2y1hKP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fKn1UWLqMs2y1hKP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fKn1UWLqMs2y1hKP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fKn1UWLqMs2y1hKP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fKn1UWLqMs2y1hKP .cluster text{fill:#333;}#mermaid-svg-fKn1UWLqMs2y1hKP .cluster span{color:#333;}#mermaid-svg-fKn1UWLqMs2y1hKP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fKn1UWLqMs2y1hKP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fKn1UWLqMs2y1hKP rect.text{fill:none;stroke-width:0;}#mermaid-svg-fKn1UWLqMs2y1hKP .icon-shape,#mermaid-svg-fKn1UWLqMs2y1hKP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fKn1UWLqMs2y1hKP .icon-shape p,#mermaid-svg-fKn1UWLqMs2y1hKP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fKn1UWLqMs2y1hKP .icon-shape .label rect,#mermaid-svg-fKn1UWLqMs2y1hKP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fKn1UWLqMs2y1hKP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fKn1UWLqMs2y1hKP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fKn1UWLqMs2y1hKP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 消息渠道
飞书
钉钉
企微
Telegram
响应适配器
格式转换
渠道适配
消息组装
决策结果
推送消息

java 复制代码
@Component
@Slf4j
public class ResponseAdapter {
    
    @Autowired
    private Map<String, MessageChannel> channels;
    
    public void send(UnifiedResponse response) {
        // 1. 获取对应的渠道适配器
        MessageChannel channel = channels.get(response.getChannelType());
        if (channel == null) {
            log.error("Channel not found: {}", response.getChannelType());
            return;
        }
        
        // 2. 发送消息
        try {
            channel.send(response);
            log.info("Response sent to channel: {}", response.getChannelType());
        } catch (Exception e) {
            log.error("Failed to send response", e);
            // 降级:尝试发送错误通知
            channel.send(UnifiedResponse.error("系统处理失败,请稍后重试"));
        }
    }
}

九、完整时序图

下面是完整端到端的时序图,展示各组件之间的交互顺序:
📋 Audit Service 📚 Learning Service 🔧 Tool Executor 🤖 LLM 🧠 Hermes Agent 🛡️ Harness 约束层 📋 Session Manager 🔀 Message Router 🌐 OpenClaw Gateway 📱 消息平台 👤 用户 📋 Audit Service 📚 Learning Service 🔧 Tool Executor 🤖 LLM 🧠 Hermes Agent 🛡️ Harness 约束层 📋 Session Manager 🔀 Message Router 🌐 OpenClaw Gateway 📱 消息平台 👤 用户 #mermaid-svg-3lqbP2Atn8dgHKcr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3lqbP2Atn8dgHKcr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3lqbP2Atn8dgHKcr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3lqbP2Atn8dgHKcr .error-icon{fill:#552222;}#mermaid-svg-3lqbP2Atn8dgHKcr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3lqbP2Atn8dgHKcr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3lqbP2Atn8dgHKcr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3lqbP2Atn8dgHKcr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3lqbP2Atn8dgHKcr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3lqbP2Atn8dgHKcr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3lqbP2Atn8dgHKcr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3lqbP2Atn8dgHKcr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3lqbP2Atn8dgHKcr .marker.cross{stroke:#333333;}#mermaid-svg-3lqbP2Atn8dgHKcr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3lqbP2Atn8dgHKcr p{margin:0;}#mermaid-svg-3lqbP2Atn8dgHKcr .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-3lqbP2Atn8dgHKcr text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-3lqbP2Atn8dgHKcr .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-3lqbP2Atn8dgHKcr .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-3lqbP2Atn8dgHKcr .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-3lqbP2Atn8dgHKcr .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-3lqbP2Atn8dgHKcr #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-3lqbP2Atn8dgHKcr .sequenceNumber{fill:white;}#mermaid-svg-3lqbP2Atn8dgHKcr #sequencenumber{fill:#333;}#mermaid-svg-3lqbP2Atn8dgHKcr #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-3lqbP2Atn8dgHKcr .messageText{fill:#333;stroke:none;}#mermaid-svg-3lqbP2Atn8dgHKcr .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-3lqbP2Atn8dgHKcr .labelText,#mermaid-svg-3lqbP2Atn8dgHKcr .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-3lqbP2Atn8dgHKcr .loopText,#mermaid-svg-3lqbP2Atn8dgHKcr .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-3lqbP2Atn8dgHKcr .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-3lqbP2Atn8dgHKcr .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-3lqbP2Atn8dgHKcr .noteText,#mermaid-svg-3lqbP2Atn8dgHKcr .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-3lqbP2Atn8dgHKcr .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-3lqbP2Atn8dgHKcr .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-3lqbP2Atn8dgHKcr .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-3lqbP2Atn8dgHKcr .actorPopupMenu{position:absolute;}#mermaid-svg-3lqbP2Atn8dgHKcr .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-3lqbP2Atn8dgHKcr .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-3lqbP2Atn8dgHKcr .actor-man circle,#mermaid-svg-3lqbP2Atn8dgHKcr line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-3lqbP2Atn8dgHKcr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} alt 需要工具调用 loop Agent Loop alt 满足学习条件- alt 约束检查失败 约束检查通过 发送消息 Webhook 回调 验签/解密 转发统一消息 getOrCreate(message) SessionContext validate(context) 记录约束检查 ❌ 拒绝执行 拒绝信息 推送拒绝消息 显示拒绝信息 ✅ 通过 decide(context, message) 构建 System Prompt 调用推理 返回响应 执行工具 工具结果 继续推理 最终响应 决策结果 触发学习评估 分析执行轨迹 生成 SKILL.md 持久化存储 响应结果 推送响应 显示响应


十、代码实现:OrchestrationService 核心编排逻辑

java 复制代码
package com.unimdp.orchestration;

@Service
@Slf4j
public class OrchestrationService {
    
    @Autowired
    private MessageRouter messageRouter;
    
    @Autowired
    private SessionManager sessionManager;
    
    @Autowired
    private HarnessConstraintService harnessConstraintService;
    
    @Autowired
    private HermesDecisionService hermesDecisionService;
    
    @Autowired
    private LearningService learningService;
    
    @Autowired
    private ResponseAdapter responseAdapter;
    
    @Autowired
    private AuditService auditService;
    
    /**
     * 核心编排方法:处理一条消息的完整链路
     */
    public OrchestrationResult process(UnifiedMessage message) {
        long startTime = System.currentTimeMillis();
        
        try {
            // 1. 阶段一:消息路由
            log.info("📥 [Phase 1] Message received: channel={}, userId={}", 
                message.getChannelType(), message.getChannelUserId());
            RoutingResult route = messageRouter.route(message);
            
            // 2. 阶段二:会话管理
            log.info("📋 [Phase 2] Session management");
            SessionContext sessionContext = sessionManager.getOrCreate(message);
            
            // 3. 阶段三:约束校验(Harness)
            log.info("🛡️ [Phase 3] Harness constraint validation");
            ToolCallContext toolContext = buildToolCallContext(message, sessionContext);
            ConstraintResult constraintResult = harnessConstraintService.validate(toolContext);
            
            if (!constraintResult.isPassed()) {
                log.warn("🔴 [Phase 3] Constraint failed: {}", constraintResult.getMessage());
                auditService.logConstraintBlock(toolContext, constraintResult);
                return OrchestrationResult.blocked(constraintResult.getMessage());
            }
            log.info("✅ [Phase 3] Constraint passed");
            
            // 4. 阶段四:智能决策(Hermes)
            log.info("🧠 [Phase 4] Hermes decision");
            DecisionResult decisionResult = hermesDecisionService.decide(
                sessionContext, message
            );
            log.info("✅ [Phase 4] Decision completed: tokens={}, toolCalls={}", 
                decisionResult.getTokenUsage(), 
                decisionResult.getToolCalls().size()
            );
            
            // 5. 阶段五:工具执行结果处理
            // (工具执行已在 Agent Loop 中完成)
            
            // 6. 阶段六:自改进(Hermes 学习循环)
            log.info("📚 [Phase 5] Learning assessment");
            Task task = buildTask(sessionContext, message, decisionResult);
            LearningResult learningResult = learningService.triggerLearning(task);
            if (learningResult.isSkillCreated()) {
                log.info("✅ [Phase 5] Skill created: {}", learningResult.getSkillName());
            }
            
            // 7. 阶段七:响应返回
            log.info("📤 [Phase 6] Response delivery");
            UnifiedResponse response = buildResponse(decisionResult, message);
            responseAdapter.send(response);
            log.info("✅ [Phase 6] Response sent");
            
            // 8. 记录审计日志
            auditService.logFullChain(sessionContext, message, decisionResult, constraintResult);
            
            long duration = System.currentTimeMillis() - startTime;
            log.info("🎯 [Complete] Full chain completed: {}ms", duration);
            
            return OrchestrationResult.success(response, duration);
            
        } catch (Exception e) {
            log.error("❌ Orchestration failed", e);
            auditService.logError(message, e);
            
            // 发送错误响应
            UnifiedResponse errorResponse = UnifiedResponse.error(
                "系统处理失败,请稍后重试"
            );
            responseAdapter.send(errorResponse);
            
            return OrchestrationResult.error(e.getMessage());
        }
    }
}

十一、总结

本文完整拆解了 Uni-MDP 中三大引擎的协同工作流:

11.1 七阶段完整链路

阶段 引擎 核心动作
① 消息接入 OpenClaw 多渠道 Webhook 接收、验签、归一化
② 会话管理 Session Manager 获取/创建会话,加载上下文
③ 约束校验 Harness 认知/权限/流程三层校验
④ 智能决策 Hermes System Prompt 组装 → Agent Loop → 工具调用
⑤ 工具执行 Tool Executor 数据查询、API 调用、文件操作
⑥ 自改进 Hermes 反馈收集 → Skill 优化 → 记忆更新
⑦ 响应返回 OpenClaw 格式转换、渠道适配、消息推送

11.2 三大引擎的协作模式

引擎 在链路中的位置 对外接口
OpenClaw 入口和出口 Webhook 接收、消息推送
Harness 决策前拦截 约束校验接口
Hermes 决策和优化核心 推理接口、学习接口

11.3 关键设计原则

  1. 责任分离:每个引擎只做自己擅长的事
  2. 安全优先:Harness 在决策前进行约束校验
  3. 可观测性:全链路审计日志,每个阶段可追溯
  4. 自进化闭环:每次执行都是学习的机会

下一篇预告:我们将深入营销决策场景实战,展示新客欢迎、加购催付、流失召回三个完整案例。

敬请期待!🚀


📌 本文收录于专栏从 OpenClaw 到 Hermes:自改进 Agent 完全指南

相关推荐
ClickHouseDB1 小时前
简化 Langfuse 的规模化应用
人工智能·数据挖掘
中微极客1 小时前
从提示词到产品级视频:生成式AI的工程化实践与工具栈选型(LTX Studio实战)
人工智能·chatgpt·音视频
@陈小鱼1 小时前
MATLAB+Python:基于小样本卷积神经网络的 PPG 血压预测
人工智能·python·机器学习·matlab·脉搏波·血压·一维卷积神经网络
大鱼>1 小时前
AI+快递分拣:视觉识别+自动分拣+异常检测
人工智能·深度学习·算法·机器学习
具身新纪元1 小时前
ECCV 2026|MATCH用Flow Matching重做多视角工业质检
人工智能·计算机视觉·视觉检测
AIHR数智引擎1 小时前
15%对撞40%:WEF白皮书里的AI组织隐忧
数据库·人工智能·经验分享·职场和发展·aihr
记忆停留w1 小时前
Celery+Redis 分布式异步任务队列工程落地业务逻辑
大数据·人工智能·redis·分布式·缓存·架构·wpf
Token炼金师1 小时前
架构的下一程:堆参数退潮,提效率登场 —— GQA、MTP、原生多模态与稀疏融合
人工智能·深度学习·llm
sunneo1 小时前
S16.6第一性原理做产品(6·收官):从《定位》到“品类设计“——AI时代如何定义新品类
人工智能·产品运营·产品经理·用户运营·用户体验·ai-native