【全域智能营销实战】1、全域智能营销决策平台技术选型:为什么是 Spring AI + OpenClaw + Hermes + Harness?

全域智能营销决策平台技术选型:为什么是 Spring AI + OpenClaw + Hermes + Harness?

从架构蓝图到技术落地的完整决策链

📑 目录


一、引言:架构蓝图很美,技术选型怎么破?

在上一篇文章中,我们完成了全域智能营销决策平台(Uni-MDP) 的架构设计------从数据层到交互层,六层三纵的完整架构蓝图已经铺开。

但架构图再漂亮,终究要落到代码层面。

一个现实的问题是:这些架构层分别用什么技术栈来实现? 是用 LangChain 还是 Spring AI?消息接入层是自己写 Webhook 还是用现成的框架?决策引擎用 Hermes 还是自己实现一套 ReAct 循环?可控性怎么保证?

这篇文章,我来详细拆解 Uni-MDP 的技术选型决策过程。为什么最终选择了 Spring AI + OpenClaw + Hermes + Harness 这套组合? 每个组件解决什么问题?它们之间如何协同?

本文是系列文章 《全域智能营销决策平台落地实战》 的第 1 篇,后续将逐篇深入代码实现。


二、回顾 Uni-MDP 总体架构:各层对技术栈的核心诉求

在开始选型之前,我们先快速回顾 Uni-MDP 的总体架构,明确每一层对技术栈的核心诉求
#mermaid-svg-QD0YFYbajh760iKv{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-QD0YFYbajh760iKv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QD0YFYbajh760iKv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QD0YFYbajh760iKv .error-icon{fill:#552222;}#mermaid-svg-QD0YFYbajh760iKv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QD0YFYbajh760iKv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QD0YFYbajh760iKv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QD0YFYbajh760iKv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QD0YFYbajh760iKv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QD0YFYbajh760iKv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QD0YFYbajh760iKv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QD0YFYbajh760iKv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QD0YFYbajh760iKv .marker.cross{stroke:#333333;}#mermaid-svg-QD0YFYbajh760iKv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QD0YFYbajh760iKv p{margin:0;}#mermaid-svg-QD0YFYbajh760iKv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QD0YFYbajh760iKv .cluster-label text{fill:#333;}#mermaid-svg-QD0YFYbajh760iKv .cluster-label span{color:#333;}#mermaid-svg-QD0YFYbajh760iKv .cluster-label span p{background-color:transparent;}#mermaid-svg-QD0YFYbajh760iKv .label text,#mermaid-svg-QD0YFYbajh760iKv span{fill:#333;color:#333;}#mermaid-svg-QD0YFYbajh760iKv .node rect,#mermaid-svg-QD0YFYbajh760iKv .node circle,#mermaid-svg-QD0YFYbajh760iKv .node ellipse,#mermaid-svg-QD0YFYbajh760iKv .node polygon,#mermaid-svg-QD0YFYbajh760iKv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QD0YFYbajh760iKv .rough-node .label text,#mermaid-svg-QD0YFYbajh760iKv .node .label text,#mermaid-svg-QD0YFYbajh760iKv .image-shape .label,#mermaid-svg-QD0YFYbajh760iKv .icon-shape .label{text-anchor:middle;}#mermaid-svg-QD0YFYbajh760iKv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QD0YFYbajh760iKv .rough-node .label,#mermaid-svg-QD0YFYbajh760iKv .node .label,#mermaid-svg-QD0YFYbajh760iKv .image-shape .label,#mermaid-svg-QD0YFYbajh760iKv .icon-shape .label{text-align:center;}#mermaid-svg-QD0YFYbajh760iKv .node.clickable{cursor:pointer;}#mermaid-svg-QD0YFYbajh760iKv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QD0YFYbajh760iKv .arrowheadPath{fill:#333333;}#mermaid-svg-QD0YFYbajh760iKv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QD0YFYbajh760iKv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QD0YFYbajh760iKv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QD0YFYbajh760iKv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QD0YFYbajh760iKv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QD0YFYbajh760iKv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QD0YFYbajh760iKv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QD0YFYbajh760iKv .cluster text{fill:#333;}#mermaid-svg-QD0YFYbajh760iKv .cluster span{color:#333;}#mermaid-svg-QD0YFYbajh760iKv 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-QD0YFYbajh760iKv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QD0YFYbajh760iKv rect.text{fill:none;stroke-width:0;}#mermaid-svg-QD0YFYbajh760iKv .icon-shape,#mermaid-svg-QD0YFYbajh760iKv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QD0YFYbajh760iKv .icon-shape p,#mermaid-svg-QD0YFYbajh760iKv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QD0YFYbajh760iKv .icon-shape .label rect,#mermaid-svg-QD0YFYbajh760iKv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QD0YFYbajh760iKv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QD0YFYbajh760iKv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QD0YFYbajh760iKv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 基础设施层 Infrastructure Layer
服务网格 Istio
消息队列 Kafka
分布式缓存 Redis
多活容灾
可观测性
算力层 Computing Layer
实时计算 Flink
离线计算 Spark
GPU加速训练
容器化 K8s
数据层 Data Layer
数据采集
多介质存储
数据治理
标签体系
数据资产化
算法层 Algorithm Layer
用户洞察算法
营销策略算法
效果预测与归因
智能优化算法
规则引擎
中台层 Capability Layer
内容中台
活动中台
权益中台
推荐中台
优惠券中台
AB实验中台
用户中台
应用层 Application Layer
全域营销洞察
智能策略中心
自动化执行
监控与优化
客户生命周期管理
交互层 Interaction Layer
可视化大屏
低代码操作台
智能问答 ChatBot
多端适配

各层对技术栈的核心诉求可以归纳为:

架构层 核心诉求 关键问题
交互层 多端适配、实时响应 前端框架选型、WebSocket 通信
应用层 业务编排、低代码 工作流引擎、规则引擎
中台层 能力复用、高并发 微服务框架、分布式事务
算法层 模型推理、在线学习 LLM 集成、MLOps
数据层 数据采集、治理、服务化 数据管道、特征存储
算力层 弹性计算、资源调度 混合计算、GPU 管理
基础设施层 高可用、可观测 服务治理、监控告警

其中最核心的挑战在于算法层和中台层的衔接------如何让 Java 生态的微服务高效地调用 LLM 能力?如何管理多模型的路由和切换?如何将 AI 的决策结果无缝对接到业务中台?

这正是 Spring AI 要解决的问题。


三、Spring AI:不止是"又一个 AI 框架"

3.1 Spring AI 的定位:AI 能力的 Spring 化抽象

很多人第一次看到 Spring AI 时,会问:"这不就是 Java 版的 LangChain 吗?"

这个理解对,但不全对

Spring AI 的核心定位不是"又一个 AI 框架",而是 AI 能力的 Spring 化抽象 。它的设计目标非常明确:让 Java/Spring 开发者用他们熟悉的方式调用 AI 能力,就像使用 Spring Data 访问数据库、使用 Spring Cloud 调用微服务一样自然。
#mermaid-svg-oxMN1NaJyuY5kzRx{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-oxMN1NaJyuY5kzRx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oxMN1NaJyuY5kzRx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oxMN1NaJyuY5kzRx .error-icon{fill:#552222;}#mermaid-svg-oxMN1NaJyuY5kzRx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oxMN1NaJyuY5kzRx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oxMN1NaJyuY5kzRx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oxMN1NaJyuY5kzRx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oxMN1NaJyuY5kzRx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oxMN1NaJyuY5kzRx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oxMN1NaJyuY5kzRx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oxMN1NaJyuY5kzRx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oxMN1NaJyuY5kzRx .marker.cross{stroke:#333333;}#mermaid-svg-oxMN1NaJyuY5kzRx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oxMN1NaJyuY5kzRx p{margin:0;}#mermaid-svg-oxMN1NaJyuY5kzRx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-oxMN1NaJyuY5kzRx .cluster-label text{fill:#333;}#mermaid-svg-oxMN1NaJyuY5kzRx .cluster-label span{color:#333;}#mermaid-svg-oxMN1NaJyuY5kzRx .cluster-label span p{background-color:transparent;}#mermaid-svg-oxMN1NaJyuY5kzRx .label text,#mermaid-svg-oxMN1NaJyuY5kzRx span{fill:#333;color:#333;}#mermaid-svg-oxMN1NaJyuY5kzRx .node rect,#mermaid-svg-oxMN1NaJyuY5kzRx .node circle,#mermaid-svg-oxMN1NaJyuY5kzRx .node ellipse,#mermaid-svg-oxMN1NaJyuY5kzRx .node polygon,#mermaid-svg-oxMN1NaJyuY5kzRx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oxMN1NaJyuY5kzRx .rough-node .label text,#mermaid-svg-oxMN1NaJyuY5kzRx .node .label text,#mermaid-svg-oxMN1NaJyuY5kzRx .image-shape .label,#mermaid-svg-oxMN1NaJyuY5kzRx .icon-shape .label{text-anchor:middle;}#mermaid-svg-oxMN1NaJyuY5kzRx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-oxMN1NaJyuY5kzRx .rough-node .label,#mermaid-svg-oxMN1NaJyuY5kzRx .node .label,#mermaid-svg-oxMN1NaJyuY5kzRx .image-shape .label,#mermaid-svg-oxMN1NaJyuY5kzRx .icon-shape .label{text-align:center;}#mermaid-svg-oxMN1NaJyuY5kzRx .node.clickable{cursor:pointer;}#mermaid-svg-oxMN1NaJyuY5kzRx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-oxMN1NaJyuY5kzRx .arrowheadPath{fill:#333333;}#mermaid-svg-oxMN1NaJyuY5kzRx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oxMN1NaJyuY5kzRx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oxMN1NaJyuY5kzRx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oxMN1NaJyuY5kzRx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-oxMN1NaJyuY5kzRx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oxMN1NaJyuY5kzRx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-oxMN1NaJyuY5kzRx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oxMN1NaJyuY5kzRx .cluster text{fill:#333;}#mermaid-svg-oxMN1NaJyuY5kzRx .cluster span{color:#333;}#mermaid-svg-oxMN1NaJyuY5kzRx 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-oxMN1NaJyuY5kzRx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oxMN1NaJyuY5kzRx rect.text{fill:none;stroke-width:0;}#mermaid-svg-oxMN1NaJyuY5kzRx .icon-shape,#mermaid-svg-oxMN1NaJyuY5kzRx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oxMN1NaJyuY5kzRx .icon-shape p,#mermaid-svg-oxMN1NaJyuY5kzRx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-oxMN1NaJyuY5kzRx .icon-shape .label rect,#mermaid-svg-oxMN1NaJyuY5kzRx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oxMN1NaJyuY5kzRx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oxMN1NaJyuY5kzRx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oxMN1NaJyuY5kzRx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 模型提供商
Spring AI 抽象层
你的 Spring 应用
Controller
Service
Repository
ChatClient
EmbeddingClient
ImageClient
ToolCallback
OpenAI
Anthropic
Google GenAI
Ollama
DeepSeek

核心抽象接口包括:

  • ChatClient :统一的对话式 AI 调用接口,支持同步、响应式流(Reactive Streams)等多种调用模式
  • EmbeddingClient :统一的文本向量化接口
  • ImageClient :统一的图像生成接口
  • ToolCallback :统一的工具/函数调用接口

这种抽象的价值在于:换模型就像换数据库驱动一样简单------只需要改一行配置,不需要改动业务代码。

3.2 2025 年模块化重构:从"大而全"到"按需引入"

2025 年,Spring AI 完成了一次根本性的模块化重构,这对企业级集成至关重要。

重构前的问题spring-ai-core 包含所有核心接口,无论你用不用都得引入,导致应用臃肿、依赖冲突频繁。

重构后的模块结构

模块 职责 依赖关系
spring-ai-commons 基础模块:核心领域模型、JSON 工具、可观测性支持 无依赖
spring-ai-model AI 功能抽象:ChatModel、EmbeddingModel、ToolCallback 依赖 commons
spring-ai-vector-store 向量数据库统一抽象 依赖 model
spring-ai-client-chat 高级对话 API:ChatClient、Advisor 链 依赖 model
spring-ai-advisors-vector-store RAG 支持:QuestionAnswerAdvisor 依赖 client-chat + vector-store
spring-ai-rag RAG 综合框架 依赖 client-chat + vector-store

#mermaid-svg-QHid5irS3zLMuJIJ{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-QHid5irS3zLMuJIJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QHid5irS3zLMuJIJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QHid5irS3zLMuJIJ .error-icon{fill:#552222;}#mermaid-svg-QHid5irS3zLMuJIJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QHid5irS3zLMuJIJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QHid5irS3zLMuJIJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QHid5irS3zLMuJIJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QHid5irS3zLMuJIJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QHid5irS3zLMuJIJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QHid5irS3zLMuJIJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QHid5irS3zLMuJIJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QHid5irS3zLMuJIJ .marker.cross{stroke:#333333;}#mermaid-svg-QHid5irS3zLMuJIJ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QHid5irS3zLMuJIJ p{margin:0;}#mermaid-svg-QHid5irS3zLMuJIJ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QHid5irS3zLMuJIJ .cluster-label text{fill:#333;}#mermaid-svg-QHid5irS3zLMuJIJ .cluster-label span{color:#333;}#mermaid-svg-QHid5irS3zLMuJIJ .cluster-label span p{background-color:transparent;}#mermaid-svg-QHid5irS3zLMuJIJ .label text,#mermaid-svg-QHid5irS3zLMuJIJ span{fill:#333;color:#333;}#mermaid-svg-QHid5irS3zLMuJIJ .node rect,#mermaid-svg-QHid5irS3zLMuJIJ .node circle,#mermaid-svg-QHid5irS3zLMuJIJ .node ellipse,#mermaid-svg-QHid5irS3zLMuJIJ .node polygon,#mermaid-svg-QHid5irS3zLMuJIJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QHid5irS3zLMuJIJ .rough-node .label text,#mermaid-svg-QHid5irS3zLMuJIJ .node .label text,#mermaid-svg-QHid5irS3zLMuJIJ .image-shape .label,#mermaid-svg-QHid5irS3zLMuJIJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-QHid5irS3zLMuJIJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QHid5irS3zLMuJIJ .rough-node .label,#mermaid-svg-QHid5irS3zLMuJIJ .node .label,#mermaid-svg-QHid5irS3zLMuJIJ .image-shape .label,#mermaid-svg-QHid5irS3zLMuJIJ .icon-shape .label{text-align:center;}#mermaid-svg-QHid5irS3zLMuJIJ .node.clickable{cursor:pointer;}#mermaid-svg-QHid5irS3zLMuJIJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QHid5irS3zLMuJIJ .arrowheadPath{fill:#333333;}#mermaid-svg-QHid5irS3zLMuJIJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QHid5irS3zLMuJIJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QHid5irS3zLMuJIJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QHid5irS3zLMuJIJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QHid5irS3zLMuJIJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QHid5irS3zLMuJIJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QHid5irS3zLMuJIJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QHid5irS3zLMuJIJ .cluster text{fill:#333;}#mermaid-svg-QHid5irS3zLMuJIJ .cluster span{color:#333;}#mermaid-svg-QHid5irS3zLMuJIJ 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-QHid5irS3zLMuJIJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QHid5irS3zLMuJIJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-QHid5irS3zLMuJIJ .icon-shape,#mermaid-svg-QHid5irS3zLMuJIJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QHid5irS3zLMuJIJ .icon-shape p,#mermaid-svg-QHid5irS3zLMuJIJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QHid5irS3zLMuJIJ .icon-shape .label rect,#mermaid-svg-QHid5irS3zLMuJIJ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QHid5irS3zLMuJIJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QHid5irS3zLMuJIJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QHid5irS3zLMuJIJ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} spring-ai-commons

基础模块
spring-ai-model

AI功能抽象
spring-ai-vector-store

向量数据库
spring-ai-client-chat

高级对话API
spring-ai-advisors-vector-store

RAG支持
spring-ai-rag

RAG综合框架

这种模块化设计的核心好处是:你只需要引入你真正用到的模块 。比如只做基础对话,只需要 spring-ai-client-chat;需要 RAG,再引入 spring-ai-rag

截至 2025 年 4 月,主分支的模块和构件结构已发生重大变化。以前 spring-ai-core 包含所有核心接口,现在已拆分为专门的领域模块,以减少应用程序中的不必要依赖。

3.3 Spring AI 2.0:工具调用的 Agentic 架构

2026 年 6 月,Spring AI 2.0.0 GA 正式发布。这次升级对 Uni-MDP 来说意义重大------它将工具调用(Tool Calling)从"埋藏在模型实现中的私有逻辑"提升为"一等公民"。

1.x 时代的问题:每个 ChatModel 实现都包含自己的工具执行循环,功能是有的,但"埋得太深"------你无法钩入、无法观测中间步骤、无法组合其他行为。

2.0 的革新 :将工具循环提升到 Advisor 链中,成为可组合的一流组件。
#mermaid-svg-8jcrOqZd8oONHZAo{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-8jcrOqZd8oONHZAo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8jcrOqZd8oONHZAo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8jcrOqZd8oONHZAo .error-icon{fill:#552222;}#mermaid-svg-8jcrOqZd8oONHZAo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8jcrOqZd8oONHZAo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8jcrOqZd8oONHZAo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8jcrOqZd8oONHZAo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8jcrOqZd8oONHZAo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8jcrOqZd8oONHZAo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8jcrOqZd8oONHZAo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8jcrOqZd8oONHZAo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8jcrOqZd8oONHZAo .marker.cross{stroke:#333333;}#mermaid-svg-8jcrOqZd8oONHZAo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8jcrOqZd8oONHZAo p{margin:0;}#mermaid-svg-8jcrOqZd8oONHZAo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8jcrOqZd8oONHZAo .cluster-label text{fill:#333;}#mermaid-svg-8jcrOqZd8oONHZAo .cluster-label span{color:#333;}#mermaid-svg-8jcrOqZd8oONHZAo .cluster-label span p{background-color:transparent;}#mermaid-svg-8jcrOqZd8oONHZAo .label text,#mermaid-svg-8jcrOqZd8oONHZAo span{fill:#333;color:#333;}#mermaid-svg-8jcrOqZd8oONHZAo .node rect,#mermaid-svg-8jcrOqZd8oONHZAo .node circle,#mermaid-svg-8jcrOqZd8oONHZAo .node ellipse,#mermaid-svg-8jcrOqZd8oONHZAo .node polygon,#mermaid-svg-8jcrOqZd8oONHZAo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8jcrOqZd8oONHZAo .rough-node .label text,#mermaid-svg-8jcrOqZd8oONHZAo .node .label text,#mermaid-svg-8jcrOqZd8oONHZAo .image-shape .label,#mermaid-svg-8jcrOqZd8oONHZAo .icon-shape .label{text-anchor:middle;}#mermaid-svg-8jcrOqZd8oONHZAo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8jcrOqZd8oONHZAo .rough-node .label,#mermaid-svg-8jcrOqZd8oONHZAo .node .label,#mermaid-svg-8jcrOqZd8oONHZAo .image-shape .label,#mermaid-svg-8jcrOqZd8oONHZAo .icon-shape .label{text-align:center;}#mermaid-svg-8jcrOqZd8oONHZAo .node.clickable{cursor:pointer;}#mermaid-svg-8jcrOqZd8oONHZAo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8jcrOqZd8oONHZAo .arrowheadPath{fill:#333333;}#mermaid-svg-8jcrOqZd8oONHZAo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8jcrOqZd8oONHZAo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8jcrOqZd8oONHZAo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8jcrOqZd8oONHZAo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8jcrOqZd8oONHZAo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8jcrOqZd8oONHZAo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8jcrOqZd8oONHZAo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8jcrOqZd8oONHZAo .cluster text{fill:#333;}#mermaid-svg-8jcrOqZd8oONHZAo .cluster span{color:#333;}#mermaid-svg-8jcrOqZd8oONHZAo 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-8jcrOqZd8oONHZAo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8jcrOqZd8oONHZAo rect.text{fill:none;stroke-width:0;}#mermaid-svg-8jcrOqZd8oONHZAo .icon-shape,#mermaid-svg-8jcrOqZd8oONHZAo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8jcrOqZd8oONHZAo .icon-shape p,#mermaid-svg-8jcrOqZd8oONHZAo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8jcrOqZd8oONHZAo .icon-shape .label rect,#mermaid-svg-8jcrOqZd8oONHZAo .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8jcrOqZd8oONHZAo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8jcrOqZd8oONHZAo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8jcrOqZd8oONHZAo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Advisor 链(有序执行)


用户请求
ChatClient
LoggingAdvisor

日志记录
ValidationAdvisor

参数校验
ToolCallingAdvisor

工具调用循环
RetryAdvisor

重试机制
需要调用工具?
执行工具
LLM 处理
返回最终响应

ToolCallingAdvisor 的工作原理

  1. 提取所有 @Tool 注解的方法,生成工具定义(名称、描述、输入参数的 JSON Schema)
  2. 将工具定义注入到初始上下文(与用户问题和系统提示一起)
  3. 每次迭代:将累积的对话历史发送给 LLM
  4. LLM 返回结果------如果包含工具调用,ToolCallingManager 执行对应工具,追加结果到对话历史,继续循环
  5. 如果返回结果不包含工具调用,将最终答案返回给用户

这为 Uni-MDP 带来的核心价值 :我们可以用 Spring AI 2.0 的 Advisor 链机制,标准化地实现 Agent 的 ReAct 循环,而不需要自己手写状态机。


四、四个开源项目的分工与选型逻辑

在 Uni-MDP 的架构中,四个开源项目各司其职、协同工作
#mermaid-svg-DMDMns4rf2ENLuFS{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-DMDMns4rf2ENLuFS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DMDMns4rf2ENLuFS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DMDMns4rf2ENLuFS .error-icon{fill:#552222;}#mermaid-svg-DMDMns4rf2ENLuFS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DMDMns4rf2ENLuFS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DMDMns4rf2ENLuFS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DMDMns4rf2ENLuFS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DMDMns4rf2ENLuFS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DMDMns4rf2ENLuFS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DMDMns4rf2ENLuFS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DMDMns4rf2ENLuFS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DMDMns4rf2ENLuFS .marker.cross{stroke:#333333;}#mermaid-svg-DMDMns4rf2ENLuFS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DMDMns4rf2ENLuFS p{margin:0;}#mermaid-svg-DMDMns4rf2ENLuFS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DMDMns4rf2ENLuFS .cluster-label text{fill:#333;}#mermaid-svg-DMDMns4rf2ENLuFS .cluster-label span{color:#333;}#mermaid-svg-DMDMns4rf2ENLuFS .cluster-label span p{background-color:transparent;}#mermaid-svg-DMDMns4rf2ENLuFS .label text,#mermaid-svg-DMDMns4rf2ENLuFS span{fill:#333;color:#333;}#mermaid-svg-DMDMns4rf2ENLuFS .node rect,#mermaid-svg-DMDMns4rf2ENLuFS .node circle,#mermaid-svg-DMDMns4rf2ENLuFS .node ellipse,#mermaid-svg-DMDMns4rf2ENLuFS .node polygon,#mermaid-svg-DMDMns4rf2ENLuFS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DMDMns4rf2ENLuFS .rough-node .label text,#mermaid-svg-DMDMns4rf2ENLuFS .node .label text,#mermaid-svg-DMDMns4rf2ENLuFS .image-shape .label,#mermaid-svg-DMDMns4rf2ENLuFS .icon-shape .label{text-anchor:middle;}#mermaid-svg-DMDMns4rf2ENLuFS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DMDMns4rf2ENLuFS .rough-node .label,#mermaid-svg-DMDMns4rf2ENLuFS .node .label,#mermaid-svg-DMDMns4rf2ENLuFS .image-shape .label,#mermaid-svg-DMDMns4rf2ENLuFS .icon-shape .label{text-align:center;}#mermaid-svg-DMDMns4rf2ENLuFS .node.clickable{cursor:pointer;}#mermaid-svg-DMDMns4rf2ENLuFS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DMDMns4rf2ENLuFS .arrowheadPath{fill:#333333;}#mermaid-svg-DMDMns4rf2ENLuFS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DMDMns4rf2ENLuFS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DMDMns4rf2ENLuFS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DMDMns4rf2ENLuFS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DMDMns4rf2ENLuFS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DMDMns4rf2ENLuFS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DMDMns4rf2ENLuFS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DMDMns4rf2ENLuFS .cluster text{fill:#333;}#mermaid-svg-DMDMns4rf2ENLuFS .cluster span{color:#333;}#mermaid-svg-DMDMns4rf2ENLuFS 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-DMDMns4rf2ENLuFS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DMDMns4rf2ENLuFS rect.text{fill:none;stroke-width:0;}#mermaid-svg-DMDMns4rf2ENLuFS .icon-shape,#mermaid-svg-DMDMns4rf2ENLuFS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DMDMns4rf2ENLuFS .icon-shape p,#mermaid-svg-DMDMns4rf2ENLuFS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DMDMns4rf2ENLuFS .icon-shape .label rect,#mermaid-svg-DMDMns4rf2ENLuFS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DMDMns4rf2ENLuFS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DMDMns4rf2ENLuFS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DMDMns4rf2ENLuFS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 消息渠道
输出层
工具执行
消息推送
数据落库
Hermes - 自进化决策引擎
Agent Loop

思考-行动循环
Learning Loop

学习循环
Skill Auto-Gen

技能自动生成
三层记忆

会话/持久/Skill
Harness - 可控性框架
约束层

权限/边界
验证层

结果校验
审计层

全量日志
Spring AI - 集成胶水层
ChatClient

统一调用
ToolCallback

工具注册
Advisor Chain

拦截链
Model Router

模型路由
OpenClaw - 消息接入层
Gateway

统一网关
Channel Adapter

渠道适配器
Session Manager

会话管理
飞书
钉钉
企微
Telegram
Slack

4.1 OpenClaw:消息接入层与渠道网关

选型理由 :OpenClaw 是一个开源的、可自托管的 AI Agent 运行时,核心定位是将 LLM 连接到多样化的消息平台和本地工具

在 Uni-MDP 中的职责:承担"消息接入层+渠道网关"------统一处理飞书、钉钉、企微、Telegram、Slack 等多渠道消息。

核心架构

组件 职责
Gateway 单个长期运行的 Node.js 进程,管理所有入站和出站通信
Channel 抽象协议特定的集成(WhatsApp、Telegram、Slack 等)
Agent 编排对话逻辑和决策
Skill 可扩展的模块,用于工具执行

Gateway 的核心机制

  • 单一 Gateway 拥有所有消息接口(WhatsApp、Telegram、Slack、Discord 等)
  • 通过 WebSocket 暴露类型化的 API(请求、响应、服务端推送事件)
  • 发出 agentchatpresencehealthheartbeatcron 等事件
  • 每台主机一个 Gateway,是唯一开启消息会话的地方

为什么选 OpenClaw 而不是自己写 Webhook?

对比维度 自己实现 OpenClaw
渠道适配 每个渠道单独开发 内置 10+ 渠道适配器
会话管理 自己维护状态 内置会话管理与持久化
消息可靠性 自己实现重试/幂等 内置幂等性 key 与去重缓存
可观测性 自己埋点 内置 health/heartbeat 事件
开发周期 数周 数小时

4.2 Hermes:自进化决策引擎

选型理由 :Hermes Agent 是首个实现"自我进化"的 AI 智能体,上线半年 GitHub 星标破 10 万。其核心差异化能力是 从执行轨迹中自动提炼并持续优化技能的学习闭环

在 Uni-MDP 中的职责:承担"自进化决策引擎"------内置学习循环,能从任务经验中提炼 Skill,实现"越用越聪明"。

核心子系统
#mermaid-svg-OfdwpT0I2OeziFOe{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-OfdwpT0I2OeziFOe .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OfdwpT0I2OeziFOe .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OfdwpT0I2OeziFOe .error-icon{fill:#552222;}#mermaid-svg-OfdwpT0I2OeziFOe .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OfdwpT0I2OeziFOe .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OfdwpT0I2OeziFOe .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OfdwpT0I2OeziFOe .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OfdwpT0I2OeziFOe .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OfdwpT0I2OeziFOe .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OfdwpT0I2OeziFOe .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OfdwpT0I2OeziFOe .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OfdwpT0I2OeziFOe .marker.cross{stroke:#333333;}#mermaid-svg-OfdwpT0I2OeziFOe svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OfdwpT0I2OeziFOe p{margin:0;}#mermaid-svg-OfdwpT0I2OeziFOe .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-OfdwpT0I2OeziFOe .cluster-label text{fill:#333;}#mermaid-svg-OfdwpT0I2OeziFOe .cluster-label span{color:#333;}#mermaid-svg-OfdwpT0I2OeziFOe .cluster-label span p{background-color:transparent;}#mermaid-svg-OfdwpT0I2OeziFOe .label text,#mermaid-svg-OfdwpT0I2OeziFOe span{fill:#333;color:#333;}#mermaid-svg-OfdwpT0I2OeziFOe .node rect,#mermaid-svg-OfdwpT0I2OeziFOe .node circle,#mermaid-svg-OfdwpT0I2OeziFOe .node ellipse,#mermaid-svg-OfdwpT0I2OeziFOe .node polygon,#mermaid-svg-OfdwpT0I2OeziFOe .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OfdwpT0I2OeziFOe .rough-node .label text,#mermaid-svg-OfdwpT0I2OeziFOe .node .label text,#mermaid-svg-OfdwpT0I2OeziFOe .image-shape .label,#mermaid-svg-OfdwpT0I2OeziFOe .icon-shape .label{text-anchor:middle;}#mermaid-svg-OfdwpT0I2OeziFOe .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OfdwpT0I2OeziFOe .rough-node .label,#mermaid-svg-OfdwpT0I2OeziFOe .node .label,#mermaid-svg-OfdwpT0I2OeziFOe .image-shape .label,#mermaid-svg-OfdwpT0I2OeziFOe .icon-shape .label{text-align:center;}#mermaid-svg-OfdwpT0I2OeziFOe .node.clickable{cursor:pointer;}#mermaid-svg-OfdwpT0I2OeziFOe .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OfdwpT0I2OeziFOe .arrowheadPath{fill:#333333;}#mermaid-svg-OfdwpT0I2OeziFOe .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OfdwpT0I2OeziFOe .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OfdwpT0I2OeziFOe .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OfdwpT0I2OeziFOe .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OfdwpT0I2OeziFOe .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OfdwpT0I2OeziFOe .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OfdwpT0I2OeziFOe .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OfdwpT0I2OeziFOe .cluster text{fill:#333;}#mermaid-svg-OfdwpT0I2OeziFOe .cluster span{color:#333;}#mermaid-svg-OfdwpT0I2OeziFOe 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-OfdwpT0I2OeziFOe .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OfdwpT0I2OeziFOe rect.text{fill:none;stroke-width:0;}#mermaid-svg-OfdwpT0I2OeziFOe .icon-shape,#mermaid-svg-OfdwpT0I2OeziFOe .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OfdwpT0I2OeziFOe .icon-shape p,#mermaid-svg-OfdwpT0I2OeziFOe .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OfdwpT0I2OeziFOe .icon-shape .label rect,#mermaid-svg-OfdwpT0I2OeziFOe .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OfdwpT0I2OeziFOe .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OfdwpT0I2OeziFOe .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OfdwpT0I2OeziFOe :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Hermes 学习闭环
工具调用>5次
出现错误并修复
用户纠正反馈
任务执行
触发条件?
Skill Auto-Generation

技能自动生成
SKILL.md 文件

~/.hermes/skills/
Skill Self-Evolution

离线批量进化
Nudge Engine

反思触发器

子系统一:Skill Auto-Generation(技能自动生成)

当任务执行中调用了 5 次以上工具、出现错误并自行修复、或用户进行了纠正反馈时,系统会触发技能生成。Agent 将本次任务的执行轨迹进行提炼,生成标准化的 SKILL.md 文件。

子系统二:Skill Self-Evolution(技能持续进化)

技能生成后并非一成不变。Hermes 内置了一套离线批量进化算法(基于 DSPy 框架和 GEPA 核心算法),会定期对已有技能进行复盘和优化。

子系统三:Nudge Engine(提醒引擎)

任务完成后的"反思触发器",定时提醒 Agent 回顾近期执行记录,判断是否有值得沉淀的经验。

实际效果 :如果你让 Hermes 写一个部署脚本,遇到依赖版本兼容性问题并成功解决,系统会自动将"问题的现象、排查步骤、最终解决方案"写成技能文件。下次再执行类似任务时,Agent 会直接绕过这个坑,Token 消耗可能从 12 次工具调用降至 6 次

为什么选 Hermes 而不是自己实现学习循环?

对比维度 自己实现 Hermes
技能自动生成 需手写规则引擎 内置触发条件与提炼逻辑
技能进化 需自己实现反馈回路 内置 DSPy + GEPA 算法
记忆管理 需自己设计三层存储 内置三层记忆架构
学习触发 需自己定义触发机制 内置 Nudge Engine

4.3 Harness:可控性框架

选型理由 :Harness Engineering 是 2026 年 AI 工程化的核心范式。其核心公式是 Agent = Model + Harness------再强大的模型,若没有适当的约束与引导,也难以发挥实际价值。

在 Uni-MDP 中的职责:承担"可控性框架"------提供约束、验证、审计能力,确保 AI Agent 在安全边界内运行。

Harness 的三大控制维度
#mermaid-svg-HCQoXSOy1RQnTqfS{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-HCQoXSOy1RQnTqfS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HCQoXSOy1RQnTqfS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HCQoXSOy1RQnTqfS .error-icon{fill:#552222;}#mermaid-svg-HCQoXSOy1RQnTqfS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HCQoXSOy1RQnTqfS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HCQoXSOy1RQnTqfS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HCQoXSOy1RQnTqfS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HCQoXSOy1RQnTqfS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HCQoXSOy1RQnTqfS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HCQoXSOy1RQnTqfS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HCQoXSOy1RQnTqfS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HCQoXSOy1RQnTqfS .marker.cross{stroke:#333333;}#mermaid-svg-HCQoXSOy1RQnTqfS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HCQoXSOy1RQnTqfS p{margin:0;}#mermaid-svg-HCQoXSOy1RQnTqfS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HCQoXSOy1RQnTqfS .cluster-label text{fill:#333;}#mermaid-svg-HCQoXSOy1RQnTqfS .cluster-label span{color:#333;}#mermaid-svg-HCQoXSOy1RQnTqfS .cluster-label span p{background-color:transparent;}#mermaid-svg-HCQoXSOy1RQnTqfS .label text,#mermaid-svg-HCQoXSOy1RQnTqfS span{fill:#333;color:#333;}#mermaid-svg-HCQoXSOy1RQnTqfS .node rect,#mermaid-svg-HCQoXSOy1RQnTqfS .node circle,#mermaid-svg-HCQoXSOy1RQnTqfS .node ellipse,#mermaid-svg-HCQoXSOy1RQnTqfS .node polygon,#mermaid-svg-HCQoXSOy1RQnTqfS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HCQoXSOy1RQnTqfS .rough-node .label text,#mermaid-svg-HCQoXSOy1RQnTqfS .node .label text,#mermaid-svg-HCQoXSOy1RQnTqfS .image-shape .label,#mermaid-svg-HCQoXSOy1RQnTqfS .icon-shape .label{text-anchor:middle;}#mermaid-svg-HCQoXSOy1RQnTqfS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HCQoXSOy1RQnTqfS .rough-node .label,#mermaid-svg-HCQoXSOy1RQnTqfS .node .label,#mermaid-svg-HCQoXSOy1RQnTqfS .image-shape .label,#mermaid-svg-HCQoXSOy1RQnTqfS .icon-shape .label{text-align:center;}#mermaid-svg-HCQoXSOy1RQnTqfS .node.clickable{cursor:pointer;}#mermaid-svg-HCQoXSOy1RQnTqfS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HCQoXSOy1RQnTqfS .arrowheadPath{fill:#333333;}#mermaid-svg-HCQoXSOy1RQnTqfS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HCQoXSOy1RQnTqfS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HCQoXSOy1RQnTqfS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HCQoXSOy1RQnTqfS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HCQoXSOy1RQnTqfS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HCQoXSOy1RQnTqfS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HCQoXSOy1RQnTqfS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HCQoXSOy1RQnTqfS .cluster text{fill:#333;}#mermaid-svg-HCQoXSOy1RQnTqfS .cluster span{color:#333;}#mermaid-svg-HCQoXSOy1RQnTqfS 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-HCQoXSOy1RQnTqfS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HCQoXSOy1RQnTqfS rect.text{fill:none;stroke-width:0;}#mermaid-svg-HCQoXSOy1RQnTqfS .icon-shape,#mermaid-svg-HCQoXSOy1RQnTqfS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HCQoXSOy1RQnTqfS .icon-shape p,#mermaid-svg-HCQoXSOy1RQnTqfS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HCQoXSOy1RQnTqfS .icon-shape .label rect,#mermaid-svg-HCQoXSOy1RQnTqfS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HCQoXSOy1RQnTqfS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HCQoXSOy1RQnTqfS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HCQoXSOy1RQnTqfS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Harness 三大控制维度
认知框架

Cognitive Framework
能力边界

Capability Boundary
行为流程

Behavioral Process
通过 agents.md

指令文件建立行为准则
规则应如地图而非法典

避免过度占用模型记忆
工具权限白名单
执行环境沙箱

本地/云端隔离
效率与安全的平衡
标准化流程

规划→生成→评估
自动迭代机制
错误中持续修正

在 Uni-MDP 中的落地方式

Harness 维度 Uni-MDP 实现
认知框架 通过 AGENTS.md 定义 Agent 的角色、目标、行为准则
能力边界 Spring AI 的 ToolCallback 白名单 + 工具调用权限校验
行为流程 Spring AI 2.0 的 Advisor 链实现"规划→执行→验证"标准化流程
审计 全量记录工具调用、决策路径,满足合规要求

4.4 Spring AI:集成胶水层

选型理由 :前面三个项目(OpenClaw、Hermes、Harness)各有所长,但它们分别用 TypeScript、Python 和"方法论"实现------如何将它们整合到一个统一的 Java 微服务体系中?

这正是 Spring AI 的职责。

在 Uni-MDP 中的职责:承担"集成胶水层"------统一管理模型调用、配置、生命周期。
#mermaid-svg-9aetVBc87M7SUlXO{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-9aetVBc87M7SUlXO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9aetVBc87M7SUlXO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9aetVBc87M7SUlXO .error-icon{fill:#552222;}#mermaid-svg-9aetVBc87M7SUlXO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9aetVBc87M7SUlXO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9aetVBc87M7SUlXO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9aetVBc87M7SUlXO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9aetVBc87M7SUlXO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9aetVBc87M7SUlXO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9aetVBc87M7SUlXO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9aetVBc87M7SUlXO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9aetVBc87M7SUlXO .marker.cross{stroke:#333333;}#mermaid-svg-9aetVBc87M7SUlXO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9aetVBc87M7SUlXO p{margin:0;}#mermaid-svg-9aetVBc87M7SUlXO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9aetVBc87M7SUlXO .cluster-label text{fill:#333;}#mermaid-svg-9aetVBc87M7SUlXO .cluster-label span{color:#333;}#mermaid-svg-9aetVBc87M7SUlXO .cluster-label span p{background-color:transparent;}#mermaid-svg-9aetVBc87M7SUlXO .label text,#mermaid-svg-9aetVBc87M7SUlXO span{fill:#333;color:#333;}#mermaid-svg-9aetVBc87M7SUlXO .node rect,#mermaid-svg-9aetVBc87M7SUlXO .node circle,#mermaid-svg-9aetVBc87M7SUlXO .node ellipse,#mermaid-svg-9aetVBc87M7SUlXO .node polygon,#mermaid-svg-9aetVBc87M7SUlXO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9aetVBc87M7SUlXO .rough-node .label text,#mermaid-svg-9aetVBc87M7SUlXO .node .label text,#mermaid-svg-9aetVBc87M7SUlXO .image-shape .label,#mermaid-svg-9aetVBc87M7SUlXO .icon-shape .label{text-anchor:middle;}#mermaid-svg-9aetVBc87M7SUlXO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9aetVBc87M7SUlXO .rough-node .label,#mermaid-svg-9aetVBc87M7SUlXO .node .label,#mermaid-svg-9aetVBc87M7SUlXO .image-shape .label,#mermaid-svg-9aetVBc87M7SUlXO .icon-shape .label{text-align:center;}#mermaid-svg-9aetVBc87M7SUlXO .node.clickable{cursor:pointer;}#mermaid-svg-9aetVBc87M7SUlXO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9aetVBc87M7SUlXO .arrowheadPath{fill:#333333;}#mermaid-svg-9aetVBc87M7SUlXO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9aetVBc87M7SUlXO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9aetVBc87M7SUlXO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9aetVBc87M7SUlXO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9aetVBc87M7SUlXO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9aetVBc87M7SUlXO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9aetVBc87M7SUlXO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9aetVBc87M7SUlXO .cluster text{fill:#333;}#mermaid-svg-9aetVBc87M7SUlXO .cluster span{color:#333;}#mermaid-svg-9aetVBc87M7SUlXO 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-9aetVBc87M7SUlXO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9aetVBc87M7SUlXO rect.text{fill:none;stroke-width:0;}#mermaid-svg-9aetVBc87M7SUlXO .icon-shape,#mermaid-svg-9aetVBc87M7SUlXO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9aetVBc87M7SUlXO .icon-shape p,#mermaid-svg-9aetVBc87M7SUlXO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9aetVBc87M7SUlXO .icon-shape .label rect,#mermaid-svg-9aetVBc87M7SUlXO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9aetVBc87M7SUlXO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9aetVBc87M7SUlXO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9aetVBc87M7SUlXO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 下游能力
Spring AI 集成胶水层
统一模型调用

ChatClient
统一工具注册

ToolCallback
统一拦截链

Advisor Chain
统一配置管理

Application Properties
统一可观测性

Micrometer Tracing
OpenClaw

消息渠道
Hermes

决策引擎
Harness

约束框架
Ollama/OpenAI

模型提供商

具体集成方式

  1. Spring AI → OpenClaw :通过 ToolCallback 将 OpenClaw 的 Skill 注册为 Spring AI 的工具,实现统一调用
  2. Spring AI → Hermes :通过 ChatClient 调用 Hermes 的 Python 服务(HTTP/gRPC),或将 Hermes 核心逻辑移植为 Spring Bean
  3. Spring AI → Harness:通过 Advisor 链实现约束校验、权限检查、审计日志

五、技术栈总览

基于以上选型分析,Uni-MDP 的完整技术栈如下:
#mermaid-svg-W1mBqLFfrSNN1O0d{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-W1mBqLFfrSNN1O0d .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-W1mBqLFfrSNN1O0d .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-W1mBqLFfrSNN1O0d .error-icon{fill:#552222;}#mermaid-svg-W1mBqLFfrSNN1O0d .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-W1mBqLFfrSNN1O0d .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-W1mBqLFfrSNN1O0d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-W1mBqLFfrSNN1O0d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-W1mBqLFfrSNN1O0d .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-W1mBqLFfrSNN1O0d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-W1mBqLFfrSNN1O0d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-W1mBqLFfrSNN1O0d .marker{fill:#333333;stroke:#333333;}#mermaid-svg-W1mBqLFfrSNN1O0d .marker.cross{stroke:#333333;}#mermaid-svg-W1mBqLFfrSNN1O0d svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-W1mBqLFfrSNN1O0d p{margin:0;}#mermaid-svg-W1mBqLFfrSNN1O0d .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-W1mBqLFfrSNN1O0d .cluster-label text{fill:#333;}#mermaid-svg-W1mBqLFfrSNN1O0d .cluster-label span{color:#333;}#mermaid-svg-W1mBqLFfrSNN1O0d .cluster-label span p{background-color:transparent;}#mermaid-svg-W1mBqLFfrSNN1O0d .label text,#mermaid-svg-W1mBqLFfrSNN1O0d span{fill:#333;color:#333;}#mermaid-svg-W1mBqLFfrSNN1O0d .node rect,#mermaid-svg-W1mBqLFfrSNN1O0d .node circle,#mermaid-svg-W1mBqLFfrSNN1O0d .node ellipse,#mermaid-svg-W1mBqLFfrSNN1O0d .node polygon,#mermaid-svg-W1mBqLFfrSNN1O0d .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-W1mBqLFfrSNN1O0d .rough-node .label text,#mermaid-svg-W1mBqLFfrSNN1O0d .node .label text,#mermaid-svg-W1mBqLFfrSNN1O0d .image-shape .label,#mermaid-svg-W1mBqLFfrSNN1O0d .icon-shape .label{text-anchor:middle;}#mermaid-svg-W1mBqLFfrSNN1O0d .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-W1mBqLFfrSNN1O0d .rough-node .label,#mermaid-svg-W1mBqLFfrSNN1O0d .node .label,#mermaid-svg-W1mBqLFfrSNN1O0d .image-shape .label,#mermaid-svg-W1mBqLFfrSNN1O0d .icon-shape .label{text-align:center;}#mermaid-svg-W1mBqLFfrSNN1O0d .node.clickable{cursor:pointer;}#mermaid-svg-W1mBqLFfrSNN1O0d .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-W1mBqLFfrSNN1O0d .arrowheadPath{fill:#333333;}#mermaid-svg-W1mBqLFfrSNN1O0d .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-W1mBqLFfrSNN1O0d .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-W1mBqLFfrSNN1O0d .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-W1mBqLFfrSNN1O0d .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-W1mBqLFfrSNN1O0d .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-W1mBqLFfrSNN1O0d .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-W1mBqLFfrSNN1O0d .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-W1mBqLFfrSNN1O0d .cluster text{fill:#333;}#mermaid-svg-W1mBqLFfrSNN1O0d .cluster span{color:#333;}#mermaid-svg-W1mBqLFfrSNN1O0d 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-W1mBqLFfrSNN1O0d .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-W1mBqLFfrSNN1O0d rect.text{fill:none;stroke-width:0;}#mermaid-svg-W1mBqLFfrSNN1O0d .icon-shape,#mermaid-svg-W1mBqLFfrSNN1O0d .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-W1mBqLFfrSNN1O0d .icon-shape p,#mermaid-svg-W1mBqLFfrSNN1O0d .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-W1mBqLFfrSNN1O0d .icon-shape .label rect,#mermaid-svg-W1mBqLFfrSNN1O0d .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-W1mBqLFfrSNN1O0d .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-W1mBqLFfrSNN1O0d .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-W1mBqLFfrSNN1O0d :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 基础设施
Istio Service Mesh
Kafka / Pulsar
Prometheus + Grafana
SkyWalking
计算层
Apache Flink
Apache Spark
Kubernetes
数据层
MySQL / PostgreSQL
Redis Cluster
ClickHouse
Elasticsearch
Apache Iceberg
Agent 层
OpenClaw Gateway

TypeScript/Node.js
Hermes Core

Python
Harness 约束框架

配置化
后端微服务 (Java)
Spring Boot 3.x
Spring Cloud 微服务
Spring AI 2.0
Spring Security
Spring Cloud Gateway
前端与交互
Vue 3 + TypeScript
ECharts 数据大屏
WebSocket 实时通信

各语言/框架的职责边界

技术组件 语言/框架 核心职责
Spring Boot 3.x Java 微服务基座、业务中台实现
Spring AI 2.0 Java 统一模型调用、工具注册、Advisor 链
OpenClaw TypeScript/Node.js 多渠道消息接入、会话管理
Hermes Python 自进化决策引擎、学习循环
Harness 配置文件 (YAML/Markdown) 约束规则、行为准则
Flink Java/Scala 实时数据流处理
ClickHouse C++ 实时 OLAP 分析
Kubernetes Go 容器编排与弹性伸缩

六、系列文章路线图

本文是系列文章的第 1 篇,后续 11 篇将从架构到代码逐层深入:

序号 主题 核心内容
第 1 篇 技术选型(本文) 为什么是 Spring AI + OpenClaw + Hermes + Harness
第 2 篇 Spring AI 模块化架构 从 1.0 到 2.0 的演进、模块拆分、核心抽象
第 3 篇 OpenClaw 源码解析 Gateway、Agent、Skill、Memory 四大模块
第 4 篇 Hermes 源码拆解 学习循环、三层 Prompt、Skill 自改进
第 5 篇 Harness 工程实践 三大控制维度的代码落地
第 6 篇 统一数据模型设计 User、Session、Memory、Skill、Task 五大实体
第 7 篇 Spring AI + OpenClaw 集成 统一消息网关与多渠道接入
第 8 篇 Spring AI + Hermes 集成 自进化能力注入营销决策引擎
第 9 篇 Harness 约束层实现 安全可控的执行环境
第 10 篇 三大引擎协同工作流 从用户消息到智能决策的完整链路
第 11 篇 营销决策场景实战 新客欢迎、加购催付、流失召回
第 12 篇 生产部署与可观测性 从开发到上线的完整 Checklist

📌 系列专栏从 OpenClaw 到 Hermes:自改进 Agent 完全指南


七、总结:选型背后的思考

回顾整个选型过程,核心决策逻辑可以总结为以下三点:

7.1 不重复造轮子,但要能掌控轮子

消息接入层有 OpenClaw,决策引擎有 Hermes,可控性有 Harness------这些都是开源社区已经验证过的成熟方案。我们的策略是 "拿来主义 + 深度集成" :用 OpenClaw 解决渠道适配的"脏活累活",用 Hermes 解决自进化的复杂逻辑,用 Spring AI 把它们"粘"在一起。

但"拿来"不等于"黑盒使用"。后续文章会深入每个项目的源码,确保我们有能力修改和扩展

7.2 统一抽象优于分散实现

如果不用 Spring AI,我们可能需要:

  • 为 OpenAI 写一套调用代码
  • 为 Anthropic 写另一套
  • 为 Ollama 再写一套
  • 工具调用逻辑每个模型单独实现

Spring AI 的抽象层让这一切统一了。换模型就像换数据库驱动------这是企业级系统的基本要求。

7.3 架构设计要为 5-8 年预留空间

Spring AI 2.0 的 Advisor 链机制、Hermes 的自进化能力、Harness 的可控性框架------这些都不是"当下够用"的方案,而是面向未来的架构。它们的设计都考虑了扩展性,能够在未来 5-8 年内持续演进,而不会因为技术债务被迫重构。


下一篇预告:我们将深入 Spring AI 的模块化架构,从 1.0 到 2.0 的演进路径、核心抽象层的设计哲学,以及如何用 Spring AI 2.0 的 Advisor 链实现 Agent 的 ReAct 循环。

敬请期待!🚀


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