# Fintec AI Framework 开发指南 ## 📚 文档目录 - [快速开始](#快速开始) - [架构概览](#架构概览) - [模块说明](#模块说明) - [使用示例](#使用示例) - [最佳实践](#最佳实践) - [常见问题](#常见问题) --- ## 快速开始 ### 环境要求 - JDK 17+ - Spring Boot 3.4.6+ - Spring AI 1.1.1+ - Maven 3.6+ ### 引入依赖 在项目的 `pom.xml` 中添加依赖: ```xml com.ccb.fintec fintec-framework-agent-spring-boot-starter com.ccb.fintec fintec-framework-rag-spring-boot-starter com.ccb.fintec fintec-framework-mcp-server-spring-boot-starter ``` ### 基础配置 在 `application.yml` 中配置 AI 模型: ```yaml spring: ai: openai: api-key: ${OPENAI_API_KEY} base-url: https://api.openai.com/v1 chat: options: model: gpt-4 temperature: 0.7 app: ai: # 安全防护 safety: enabled: true block-keywords: - 暴力 - 色情 - 赌博 # 限流配置 rate-limit: max-requests-per-minute: 60 # 重试策略(自动处理网络波动) retry: enabled: true max-attempts: 3 backoff-ms: 1000 ``` --- ## 架构概览 ### 整体架构 ``` ┌─────────────────────────────────────────────┐ │ 业务应用层 (Business App) │ ├─────────────────────────────────────────────┤ │ Agent+Graph+MCP Client │ RAG │ │ Starter │ Starter │ ├─────────────────────────────────────────────┤ │ Core 核心层 (统一抽象) │ ├─────────────────────────────────────────────┤ │ Spring AI (模型适配层) │ ├─────────────────────────────────────────────┤ │ OpenAI │ Ollama │ Anthropic │ 其他模型 │ └─────────────────────────────────────────────┘ ↑ ┌─────────────────────────────────────────────┐ │ MCP Server (独立部署) │ │ SSE + STDIO + Streamable-HTTP │ └─────────────────────────────────────────────┘ ``` ### 设计原则 1. **分层解耦**: 技术实现与业务编排分离 2. **多模型支持**: 通过 Spring AI 抽象,支持切换不同模型厂商 3. **开箱即用**: 自动配置,零样板代码 4. **可扩展性**: 基于 Spring Boot Starter 机制,易于扩展 --- ## 模块说明 ### 1. fintec-framework-ai-core (核心模块) **职责**: 提供统一的 AI 配置和能力抽象 **功能**: - 全局 AI 配置管理 (`AiCoreProperties`) - 公共的接口和DTO,公共回复等解耦... --- ### 2. fintec-framework-agent-spring-boot-starter (Agent 模块) **职责**: 提供对话式 AI、Graph 工作流编排和 MCP Client 能力 **核心组件**: - `AgentTemplate`: 封装常用对话模式(内置重试) - `MultimodalTemplate`: 多模态能力(图片/文档理解) - `ChatClient`: 统一的聊天客户端 - `ChatMemory`: 对话记忆管理 - Graph 工作流: `Node`, `Condition`, `SequentialWorkflow`, `ParallelWorkflow`, `RoutingWorkflow`, `LoopWorkflow` - `McpClientAutoConfiguration`: MCP Client 自动配置 - `RetryAutoConfiguration`: 自动重试机制 - `SafetyAspect`: 敏感词过滤切面 **主要功能**: - 简单问答 - 带系统提示的对话 - Function Calling(工具调用) - 结构化输出 - 流式响应 - 对话记忆 - **图片理解**: 分析图片内容、OCR识别 - **Graph 工作流**: Sequential/Parallel/Routing/Loop - **MCP Client**: 连接外部 MCP Server - **安全防护**: 敏感词过滤(请求+响应双向检查) - **自动重试**: 处理网络波动、临时故障 **典型场景**: 智能客服、AI助手、代码生成、多模态应用、复杂工作流编排 --- ### 3. fintec-framework-rag-spring-boot-starter (RAG 模块) **职责**: 提供检索增强生成、ETL 和图片生成能力 **核心组件**: - `RagTemplate`: 封装 RAG 调用模式 - `ImageGenerationTemplate`: 图片生成能力 - `QuestionAnswerAdvisor`: 向量检索顾问 **主要功能**: - **ETL**: 文档读取和解析(PDF、Word、TXT等) - **Embedding**: 文本向量化 - **VectorStore**: 向量存储和检索 - 基于知识库的问答 - 自定义相似度阈值和 TopK - 流式输出 - 结合对话记忆 - **图片生成**: 根据文本描述生成图片 **典型场景**: 企业知识库问答、文档检索、智能搜索、AI绘画 --- ### 4. fintec-framework-mcp-server-spring-boot-starter (MCP Server 模块) **职责**: 提供 Model Context Protocol Server 支持,将工具暴露给外部 Agent **核心组件**: - `McpAutoConfiguration`: MCP Server 自动配置 - `ToolCallbackProvider`: 自动扫描 `@Tool` 注解 **主要功能**: - 自动注册工具函数 - **SSE**: Server-Sent Events 传输 - **STDIO**: 标准输入输出传输 - **Streamable-HTTP**: 流式 HTTP 传输 - 工具发现与调用 **典型场景**: AI 调用外部 API、数据库查询、业务系统集成(独立部署) --- ## 使用示例 ### Agent 模块示例(包含 Graph 工作流) ```java @Service public class CustomerService { @Autowired private AgentTemplate agentTemplate; // 简单问答 public String answer(String question) { return agentTemplate.ask(question); } // 带系统提示 public String answerWithRole(String question) { return agentTemplate.ask( "你是一位专业的客服代表,请用礼貌的语气回答", question ); } // 流式输出 public Flux streamAnswer(String question) { return agentTemplate.stream(question); } // 带对话记忆 public String chat(String conversationId, String message) { return agentTemplate.askWithMemory(conversationId, message); } // 结构化输出 public OrderInfo extractOrder(String text) { return agentTemplate.askForObject( "从以下文本中提取订单信息: " + text, OrderInfo.class ); } } ``` ### Graph 工作流示例 ```java @Service public class WorkflowService { @Autowired private GraphTemplate graphTemplate; // 顺序工作流: 数据清洗 -> 翻译 -> 总结 public String processText(String text) { var workflow = GraphTemplate.sequential( GraphTemplate.node("清洗", t -> t.trim()), GraphTemplate.node("翻译", t -> translate(t)), GraphTemplate.node("总结", t -> summarize(t)) ); return workflow.execute(text); } // 并行工作流: 多维度分析 public List analyzeText(String text) { var workflow = GraphTemplate.parallel( GraphTemplate.node("情感分析", t -> sentiment(t)), GraphTemplate.node("关键词提取", t -> keywords(t)), GraphTemplate.node("分类", t -> classify(t)) ); return workflow.execute(text); } // 路由工作流: 根据问题类型选择处理逻辑 public String routeQuestion(String question) { var workflow = GraphTemplate.routing() .addBranch("技术", q -> ((String)q).contains("技术"), GraphTemplate.node("技术回答", q -> techAnswer(q))) .addBranch("业务", q -> ((String)q).contains("业务"), GraphTemplate.node("业务回答", q -> businessAnswer(q))) .setDefault(GraphTemplate.node("通用回答", q -> generalAnswer(q))); return workflow.execute(question); } } ``` ```java @Service public class KnowledgeService { @Autowired private RagTemplate ragTemplate; // 基于知识库问答 public String askKnowledge(String question) { return ragTemplate.ask(question); } // 自定义检索参数 public String askWithConfig(String question) { return ragTemplate.askWithConfig( question, 0.8, // 相似度阈值 5 // TopK ); } // 流式输出 public Flux streamAsk(String question) { return ragTemplate.stream(question); } } ``` ### Graph 模块示例 ```java @Service public class WorkflowService { @Autowired private GraphTemplate graphTemplate; // 顺序工作流: 数据清洗 -> 翻译 -> 总结 public String processText(String text) { var workflow = GraphTemplate.sequential( GraphTemplate.node("清洗", t -> t.trim()), GraphTemplate.node("翻译", t -> translate(t)), GraphTemplate.node("总结", t -> summarize(t)) ); return workflow.execute(text); } // 并行工作流: 多维度分析 public List analyzeText(String text) { var workflow = GraphTemplate.parallel( GraphTemplate.node("情感分析", t -> sentiment(t)), GraphTemplate.node("关键词提取", t -> keywords(t)), GraphTemplate.node("分类", t -> classify(t)) ); return workflow.execute(text); } // 路由工作流: 根据问题类型选择处理逻辑 public String routeQuestion(String question) { var workflow = GraphTemplate.routing() .addBranch("技术", q -> ((String)q).contains("技术"), GraphTemplate.node("技术回答", q -> techAnswer(q))) .addBranch("业务", q -> ((String)q).contains("业务"), GraphTemplate.node("业务回答", q -> businessAnswer(q))) .setDefault(GraphTemplate.node("通用回答", q -> generalAnswer(q))); return workflow.execute(question); } } ``` --- ## 最佳实践 ### 1. 对话记忆管理 ✅ **推荐做法**: ```java // 使用业务ID作为会话ID String conversationId = "user_" + userId + "_session_" + sessionId; agentTemplate.askWithMemory(conversationId, message); // 定期清理过期会话 @Component public class MemoryCleanupTask { @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点 public void cleanup() { // 清理7天前的会话 } } ``` ❌ **避免做法**: - 使用 UUID 作为会话ID(每次都是新会话) - 不清理会话数据(内存泄漏) - 不同用户共用同一会话ID --- ### 3. RAG 优化 ✅ **推荐做法**: ```java // 调整相似度阈值(根据业务场景) ragTemplate.askWithConfig(question, 0.75, 3); // 文档切片策略 // - 技术文档: 500-800 tokens/chunk // - FAQ: 按问题拆分 // - 合同: 按条款拆分 // 添加元数据过滤 SearchRequest.builder() .similarityThreshold(0.8) .topK(5) .filterExpression("category == 'technical'") .build(); ``` ❌ **避免做法**: - TopK 设置过大(增加成本) - 相似度阈值过低(返回不相关内容) - 不处理文档切片重叠 --- ### 4. 工作流设计 ✅ **推荐做法**: ```java // 为节点命名(便于调试) GraphTemplate.node("数据验证", data -> validate(data)); // 设置合理的循环上限 GraphTemplate.loop(node, condition, 5); // 最多5次迭代 // 异常处理 try { return workflow.execute(input); } catch (Exception e) { log.error("工作流执行失败", e); return fallbackResult; } ``` ❌ **避免做法**: - 循环不设上限(死循环风险) - 节点逻辑过于复杂(应拆分为多个节点) - 不记录工作流执行日志 --- ### 5. 性能优化 ✅ **推荐做法**: ```java // 使用流式输出提升用户体验 @GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux streamChat(String message) { return agentTemplate.stream(message); } // 并行执行独立任务 var results = GraphTemplate.parallel( node1, node2, node3 ).execute(input); // 缓存常见问题的答案 @Cacheable(value = "faq", key = "#question") public String getFaqAnswer(String question) { return ragTemplate.ask(question); } ``` ❌ **避免做法**: - 同步等待大模型响应(超时风险) - 串行执行可并行的任务 - 重复调用相同的 Prompt --- ## 常见问题 ### Q1: 如何切换不同的 AI 模型? **A**: 修改 `application.yml` 配置即可: ```yaml # 切换到 Ollama spring: ai: ollama: base-url: http://localhost:11434 chat: options: model: llama3 # 切换到通义千问 spring: ai: dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-max ``` --- ### Q2: 如何实现多轮对话? **A**: 使用 `askWithMemory` 方法: ```java // 第一次对话 String answer1 = agentTemplate.askWithMemory("session_001", "你好"); // 第二次对话(能记住上下文) String answer2 = agentTemplate.askWithMemory("session_001", "我刚才说了什么?"); ``` --- ### Q3: RAG 检索不到相关内容怎么办? **A**: 检查以下几点: 1. 降低相似度阈值(如从 0.8 降到 0.6) 2. 增加 TopK 数量 3. 优化文档切片策略 4. 检查 Embedding 模型质量 5. 添加更多相关文档 --- ### Q4: 如何调试工作流? **A**: 启用 DEBUG 日志: ```yaml logging: level: com.ccb.fintec.graph: DEBUG ``` 查看每个节点的输入输出和执行时间。 --- ### Q5: 如何保证 AI 输出的安全性? **A**: 多层防护: 1. 配置敏感词过滤 (`app.ai.safety.block-keywords`) 2. 设置输出长度限制 (`max-tokens-per-request`) 3. 人工审核关键业务输出