自研 AI Agent 框架 · ReAct 模式 + Agentic RAG + MCP 协议扩展 + 多 Agent 工作流 (StateGraph) 编排
全栈 AI 智能体系统,自底向上实现了 Agent 完整的技术栈:对话记忆 → 结构化输出 → RAG 知识增强 → 工具调用 → MCP 协议 → ReAct 智能体 → 多 Agent Graph 编排。所有 Agent 核心机制(循环控制、工具执行、状态管理、流式推送)均自行实现,不依赖框架内置自动化。
| 维度 | 能力 | 技术实现 |
|---|---|---|
| Agent 框架 | 自研 ReAct Agent 框架 | 四层继承 (BaseAgent → ReActAgent → ToolCallAgent → ZhouManus),状态机 (IDLE→RUNNING→FINISHED/ERROR),手动工具调用控制,Terminate 主动终止 + maxSteps 兜底 |
| RAG Pipeline | Agentic RAG 检索生成 | LLM 路由决策 + 混合检索 (Hybrid Search: 向量 PGVector + 关键词 ILIKE) + 多轮反思循环 + 兜底直答 |
| MCP 协议 | 运行时动态工具扩展 | 基于 MCP 协议的 SSE/stdio 双模式热插拔,WatchService 配置文件热加载,REST API 运行时注册 |
| 多 Agent 工作流 | Graph 有向图编排 | 基于 StateGraph 的 7 节点条件路由,Flux.concat() + Flux.defer() 实现真逐节点 SSE 推送,NonTransientAiException 降级容错 |
| 流式架构 | 多方案同项目对比 | Flux / SseEmitter / ServerSentEvent 多种实现 |
| 可观测性 | 本地部署 Langfuse3 全链路追踪 | OpenTelemetry OTLP 协议原生对接,Span 级记录 Agent 思考-行动-结果全过程 |
| 目录 | 技术栈 | 说明 |
|---|---|---|
src/ |
Spring Boot 3.4 + Spring AI | 后端主应用(智能体、RAG、工具、API) |
zhou-ai-agent-frontend/ |
Vue 3 + Vite + TypeScript | 聊天界面前端(双模式对话界面) |
zhou-image-search-mcp-server/ |
Spring Boot 3.4 + MCP Server | 图像搜索 MCP 服务(Pexels API) |
后端 Backend
- Java 21, Spring Boot 3.4.4, Spring AI 1.0.0
- Spring AI Alibaba + DashScope(通义千问 Qwen)
- StateGraph(多 Agent 工作流编排引擎,条件路由 + 状态管理)
- ReactAgent(Alibaba Cloud Graph React 代理框架,ReAct 模式)
- PGVector(PostgreSQL 向量数据库)
- Knife4j / OpenAPI 3(API 文档)
- iTextPDF, Jsoup, Hutool, Kryo
- Micrometer Tracing + OpenTelemetry(可观测性)
- Langfuse(AI 可观测性平台)
前端 Frontend
- Vue 3.5, TypeScript, Vite 6
- Vue Router 4, Axios
MCP Server
- Spring Boot 3.4.5, Spring AI MCP Server
- Pexels API(图像搜索)
基础设施 Infrastructure
- Docker Compose(一键启动 Langfuse + PostgreSQL)
- PostgreSQL + pgvector(向量存储 + 记忆持久化)
- JDK 21
- Node.js 18+
- PostgreSQL(可选,用于 PGVector 持久化向量存储)
- Maven 3.9+
在启动前,需要配置以下 API Key:
| 配置项 | 文件位置 | 说明 |
|---|---|---|
spring.ai.dashscope.api-key |
src/main/resources/application.yaml |
阿里云 DashScope API Key(通义千问模型) |
search-api.api-key |
src/main/resources/application.yaml |
SearchAPI.io API Key(网页搜索功能) |
AMAP_MAPS_API_KEY |
src/main/resources/mcp-servers.json |
高德地图 MCP Server API Key |
| Pexels API Key | zhou-image-search-mcp-server/src/main/resources/application.yaml |
图像搜索 MCP Server 的 Pexels API Key |
# 配置好 API Key 后
mvn spring-boot:run
# 后端运行在 http://localhost:8123/apicd zhou-ai-agent-frontend
npm install
npm run dev
# 前端运行在 http://localhost:5173,自动代理 /api 到后端 8123 端口cd zhou-image-search-mcp-server
# 配置 Pexels API Key
mvn spring-boot:run
# MCP Server 运行在 http://localhost:8127| 接口 | 方法 | 说明 |
|---|---|---|
/api/ai/love_app/chat/sync |
GET | 同步对话(AI 情感大师) |
/api/ai/love_app/chat/sse |
GET | SSE 流式对话(Flux 方式) |
/api/ai/love_app/chat/server_sent_event |
GET | SSE 流式对话(ServerSentEvent 包装) |
/api/ai/love_app/chat/sse_emitter |
GET | SSE 流式对话(SseEmitter 方式) |
/api/ai/manus/chat |
GET | 智能体流式对话(ZhouManus,SseEmitter) |
/api/ai/manus/chat/flux |
GET | 智能体流式对话(ZhouManus,Flux 推荐) |
/api/mcp/servers |
GET | 列出所有已注册的 MCP Server |
/api/mcp/servers |
POST | 注册新的 MCP Server |
/api/mcp/servers/{name} |
DELETE | 移除 MCP Server |
/api/mcp/servers/refresh |
POST | 从配置文件重新加载 MCP Server |
/api/mcp/servers/tools |
GET | 列出所有可用工具 |
/engine/agent/decide/stream |
GET/POST | 投资决策流式接口(SSE,代理至 agent-decision-engine) |
/engine/agent/health |
GET | 决策引擎健康检查 |
/health |
GET | 健康检查 |
/actuator |
GET | Spring Boot Actuator 端点 |
API 文档访问:http://localhost:8123/api/swagger-ui.html(Knife4j)
Langfuse 可观测性面板:http://localhost:3000(docker-compose 启动后)
ZhouManus 采用四层继承架构,实现「思考 → 行动」的自主循环:
┌─────────────────────────────────────────────┐
│ ZhouManus │
│ (具体智能体,配置提示词和工具) │
├─────────────────────────────────────────────┤
│ ToolCallAgent │
│ think(): 调用 LLM 判断是否需要工具 │
│ act(): 手动执行 LLM 选择的工具 │
├─────────────────────────────────────────────┤
│ ReActAgent │
│ step() = think() + act() │
│ 先思考再行动的循环模式 │
├─────────────────────────────────────────────┤
│ BaseAgent │
│ Agent Loop: 最多执行 maxSteps 步 │
│ 状态管理: IDLE → RUNNING → FINISHED/ERROR │
│ 会话记忆: 维护 messageList 上下文 │
└─────────────────────────────────────────────┘
BaseAgent(基础层) — 负责"循环引擎":定义 agent 主循环,最多跑 20 步,管理状态机(空闲 → 运行中 → 完成/出错),维护对话记忆。子类只需实现 step() 方法定义每一步做什么。
ReActAgent(推理层) — 实现"先想后做"模式:把 step() 拆成 think()(思考)和 act()(行动)两个抽象方法。这层只定义执行顺序,不关心具体怎么思考、怎么行动。
ToolCallAgent(工具层) — 实现具体的思考和行动:think() 调用 LLM,让大模型判断需要哪些工具;act() 手动执行这些工具(禁用了 Spring AI 内置的自动工具调用,改为手动控制)。
ZhouManus(应用层) — 具体的智能体实例:配置系统提示词("你是全能助手")、接入所有工具、设置最大步数。
终止机制:两种方式跳出循环 — ① 调用 TerminateTool(大模型判断任务完成时主动调用);② 达到最大步数 20 步(兜底保护,防止无限循环)。
内置工具(src/main/java/com/zhou/zhouaiagent/tools/):
| 工具 | 说明 |
|---|---|
TerminateTool |
终止智能体执行,通知 Agent 任务已完成 |
WebSearchTool |
百度网页搜索(通过 SearchAPI.io,返回前 5 条结果) |
WebScrapingTool |
网页内容抓取(基于 Jsoup) |
FileOperationTool |
文件读写操作(操作 tmp/file/ 目录) |
TerminalOperationTool |
执行终端/Shell 命令 |
PDFGenerationTool |
生成 PDF 文档(iTextPDF,支持中文字体) |
ResourceDownloadTool |
从 URL 下载资源文件(保存到 tmp/download/) |
MCP 扩展工具:
| 工具 | 来源 | 说明 |
|---|---|---|
searchImage |
自定义 MCP Server | 通过 Pexels API 搜索图片(zhou-image-search-mcp-server) |
amap-maps 系列工具 |
高德地图 MCP | 地理编码、路径规划、POI 搜索等地图服务(@amap/amap-maps-mcp-server) |
docker build -t zhou-ai-agent .
docker run -p 8123:8123 zhou-ai-agent# 启动所有服务(Langfuse + PostgreSQL + pgvector)
docker-compose up -d
# 服务列表:
# - Langfuse: http://localhost:3000(可观测性面板)
# - PostgreSQL (Langfuse): localhost:5432
# - PostgreSQL (pgvector): localhost:5433
# 停止服务
docker-compose down基于 JdbcChatMemoryRepository 实现会话记忆的持久化存储,服务重启后会话不丢失。
┌─────────────────────────────────────────────────┐
│ MessageWindowChatMemory │
│ 滑动窗口:保留最近 20 条消息 │
├─────────────────────────────────────────────────┤
│ JdbcChatMemoryRepository │
│ 存储:type + content + metadata 三列 │
│ 序列化:Jackson JSON(避免 Kryo 兼容性问题) │
├─────────────────────────────────────────────────┤
│ PostgreSQL + JDBC │
│ 自动建表,支持多会话隔离 │
└─────────────────────────────────────────────────┘
支持运行时动态添加/移除 MCP Server,无需重启服务。启动时自动从 mcp-servers.json 加载所有 MCP Server 配置。
┌─────────────────────────────────────────────────┐
│ McpServerController │
│ REST API: POST/DELETE/GET /mcp/servers │
├─────────────────────────────────────────────────┤
│ McpToolRegistry │
│ @PostConstruct 启动时自动加载 mcp-servers.json │
│ 支持 SSE 和 stdio 两种传输模式 │
│ ConcurrentHashMap 管理所有 MCP Server 连接 │
├─────────────────────────────────────────────────┤
│ DynamicToolCallbackProvider │
│ 统一管理:内置工具 + MCP 工具 + 动态工具 │
│ ZhouManus 通过此 Provider 获取完整工具列表 │
├─────────────────────────────────────────────────┤
│ McpConfigFileWatcher │
│ WatchService 监听 mcp-servers.json 文件变更 │
│ 文件修改时自动刷新 MCP Server 连接 │
└─────────────────────────────────────────────────┘
配置文件位于 src/main/resources/mcp-servers.json,支持两种模式:
SSE 模式 — 连接独立运行的 MCP Server(需先单独启动):
{
"mcpServers": {
"server-name": {
"url": "http://localhost:8127"
}
}
}stdio 模式 — 自动启动 MCP Server 子进程(通过 stdin/stdout 通信):
{
"mcpServers": {
"server-name": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.stdio=true",
"-Dspring.main.web-application-type=none",
"-Dspring.main.banner-mode=off",
"-Dspring.main.log-startup-info=false",
"-Dlogging.level.root=WARN",
"-Dlogging.pattern.console=",
"-jar",
"/absolute/path/to/your-mcp-server.jar"
],
"env": {}
}
}
}重要:stdio 模式下 jar 路径必须使用绝对路径,且必须包含完整的 jar 包文件。使用相对路径时,工作目录不同会导致找不到 jar 包。同时需要通过 JVM 参数彻底抑制 Spring Boot 的 stdout 输出(banner、日志等),否则非 JSON 内容会污染 MCP stdio 协议通信,导致
MismatchedInputException或连接超时。
可仿照 springai集成langfuse3示例 github
通过 OpenTelemetry 协议原生集成 Langfuse 3,无 Langfuse SDK 依赖。
┌─────────────────────────────────────────────────┐
│ Langfuse 3 面板 │
│ 可视化 Agent 执行链路、Token 消耗、延迟 │
│ 展示 prompt/completion 完整对话内容 │
├─────────────────────────────────────────────────┤
│ OpenTelemetry OTLP Exporter │
│ OTLP/HTTP → Langfuse /api/public/otel │
├─────────────────────────────────────────────────┤
│ micrometer-tracing-bridge-otel │
│ Micrometer Observation → OTel Span 桥接 │
├─────────────────────────────────────────────────┤
│ ChatModelCompletionContentObservationFilter │
│ 注入 gen_ai.prompt / gen_ai.completion │
├─────────────────────────────────────────────────┤
│ Spring AI Observation + @Observed 注解 │
│ ChatModel.call() → spring_ai chat_client │
│ BaseAgent.run() → agent.run │
│ ToolCallAgent.think() → agent.think │
│ ToolCallAgent.act() → agent.act │
└─────────────────────────────────────────────────┘
LLM 作为代理自主决策的完整 RAG Pipeline,整合混合检索与多轮反思机制。
┌─────────────────────────────────────────────────┐
│ LLM Route Agent │
│ 自主判断:RETRIEVE(检索)/ DIRECT_ANSWER(直答)│
├─────────────────────────────────────────────────┤
│ RewriteQueryTransformer │
│ 查询改写,优化检索词 │
├─────────────────────────────────────────────────┤
│ HybridDocumentRetriever │
│ 向量检索:语义相似度(PGVector COSINE) │
│ 关键词检索:ILIKE 精确匹配(PostgreSQL 原生) │
│ 合并去重:LinkedHashMap 按 ID 去重 │
├─────────────────────────────────────────────────┤
│ LLM Retrieval Evaluator │
│ 评估检索质量:SUFFICIENT / RE_RETRIEVE / GIVE_UP│
│ 多轮反思:最多 2 轮,LLM 生成改进检索词 │
├─────────────────────────────────────────────────┤
│ 兜底策略 │
│ 检索为空 → LLM 直接回答 │
│ 检索有结果 → 构建上下文 → LLM 基于资料回答 │
└─────────────────────────────────────────────────┘
统一使用 Flux<String> 实现线程安全的流式输出。
// BaseAgent.runStreamFlux() 核心实现
Flux.create(sink -> {
Schedulers.boundedElastic().schedule(() -> {
for (int i = 0; i < maxSteps; i++) {
String stepResult = step();
sink.next("Step " + (i+1) + ": " + stepResult);
}
sink.complete();
});
}, FluxSink.OverflowStrategy.BUFFER);前端集成独立的 agent-decision-engine 服务,提供 7 节点 Multi-Agent Graph 流式投资决策功能。
┌────────────────────────────────────────────┐
│ zhou-ai-agent (Vue 3 前端) │
│ DecisionEngineView.vue │
│ ├── decisionEngine.ts (axios) │
│ ├── decisionEngine-sync.ts (fetch SSE) │
│ └── decisionEngine-fixed.ts (POST SSE) │
├────────────────────────────────────────────┤
│ Vite 代理: /engine → localhost:8182/api │
├────────────────────────────────────────────┤
│ agent-decision-engine (后端) │
│ MultiAgentInvestService │
│ ├── IntentClassifyAgent (意图分类) │
│ ├── ProblemPerceptionAgent (问题感知) │
│ ├── KnowledgeRetrievalAgent (知识检索) │
│ ├── DataFetchAgent (数据获取) │
│ ├── ReasoningAnalysisAgent (推理分析) │
│ ├── DecisionGenerateAgent (决策生成) │
│ └── GraphScheduleAgent (汇总输出) │
└────────────────────────────────────────────┘
决策流程:用户输入投资需求 → 意图分类(非投资直接返回)→ 问题感知 → 知识检索(ReAct)→ 数据获取(ReAct)→ 推理分析 → 决策生成 → 汇总输出,7 个步骤通过 SSE 流式推送到前端。




