# API 参考文档 ## 📚 模块索引 - [AgentTemplate API](#agenttemplate-api) - [RagTemplate API](#ragtemplate-api) - [GraphTemplate API](#graphtemplate-api) - [配置项说明](#配置项说明) --- ## AgentTemplate API ### 类说明 `com.ccb.fintec.agent.template.AgentTemplate` 封装 Spring AI ChatClient 的常用调用模式,提供简洁的对话能力。 ### 构造方法 ```java public AgentTemplate(ChatClient chatClient) ``` **参数**: - `chatClient`: Spring AI 聊天客户端(由自动配置提供) --- ### 方法列表 #### 1. ask(String question) 简单问答 **签名**: ```java public String ask(String question) ``` **参数**: - `question`: 用户问题 **返回**: AI 的回答 **示例**: ```java String answer = agentTemplate.ask("什么是Spring AI?"); ``` --- #### 2. ask(String systemPrompt, String question) 带系统提示的问答 **签名**: ```java public String ask(String systemPrompt, String question) ``` **参数**: - `systemPrompt`: 系统提示词,定义 AI 角色和行为 - `question`: 用户问题 **返回**: AI 的回答 **示例**: ```java String answer = agentTemplate.ask( "你是一位专业的Java工程师", "如何优化Stream性能?" ); ``` --- #### 3. askWithTools(String question, Object... toolObjects) 带工具调用的问答 **签名**: ```java public String askWithTools(String question, Object... toolObjects) ``` **参数**: - `question`: 用户问题 - `toolObjects`: 包含 `@Tool` 注解的对象 **返回**: AI 的回答(可能包含工具调用结果) **示例**: ```java @Service public class WeatherService { @Tool(description = "查询天气") public String getWeather(String city) { return weatherApi.query(city); } } // 使用 String answer = agentTemplate.askWithTools( "北京今天天气怎么样?", new WeatherService() ); ``` --- #### 4. askForObject(String question, Class responseType) 结构化输出 **签名**: ```java public T askForObject(String question, Class responseType) ``` **参数**: - `question`: 用户问题 - `responseType`: 期望的返回类型 **返回**: 解析后的 Java 对象 **示例**: ```java @Data public class PersonInfo { private String name; private Integer age; private String email; } PersonInfo info = agentTemplate.askForObject( "从以下文本提取个人信息: 我叫张三,今年25岁,邮箱zhangsan@example.com", PersonInfo.class ); ``` --- #### 5. stream(String question) 流式输出 **签名**: ```java public Flux stream(String question) ``` **参数**: - `question`: 用户问题 **返回**: 响应式流,逐块返回 AI 回答 **示例**: ```java @GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux> streamChat(String message) { return agentTemplate.stream(message) .map(chunk -> ServerSentEvent.builder(chunk).build()); } ``` --- #### 6. streamWithMemory(String conversationId, String question) 带记忆的流式输出 **签名**: ```java public Flux streamWithMemory(String conversationId, String question) ``` **参数**: - `conversationId`: 会话ID - `question`: 用户问题 **返回**: 响应式流 **示例**: ```java Flux response = agentTemplate.streamWithMemory( "user_123_session_456", "我刚才问了什么?" ); ``` --- #### 7. askWithMemory(String conversationId, String question) 带记忆的多轮对话 **签名**: ```java public String askWithMemory(String conversationId, String question) ``` **参数**: - `conversationId`: 会话ID - `question`: 用户问题 **返回**: AI 的回答 **示例**: ```java // 第一轮 String answer1 = agentTemplate.askWithMemory("session_001", "我叫张三"); // 第二轮(AI 记得用户的名字) String answer2 = agentTemplate.askWithMemory("session_001", "我叫什么名字?"); // 回答: "你叫张三" ``` --- ## RagTemplate API ### 类说明 `com.ccb.fintec.rag.template.RagTemplate` 封装检索增强生成(RAG)能力,基于向量数据库实现知识库问答。 ### 构造方法 ```java public RagTemplate(ChatClient chatClient, VectorStore vectorStore) ``` **参数**: - `chatClient`: Spring AI 聊天客户端 - `vectorStore`: 向量数据库 --- ### 方法列表 #### 1. ask(String question) 基于知识库问答 **签名**: ```java public String ask(String question) ``` **参数**: - `question`: 用户问题 **返回**: 基于知识库的回答 **示例**: ```java String answer = ragTemplate.ask("公司的报销流程是什么?"); ``` --- #### 2. stream(String question) 基于知识库的流式问答 **签名**: ```java public Flux stream(String question) ``` **参数**: - `question`: 用户问题 **返回**: 响应式流 **示例**: ```java @GetMapping(value = "/rag/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux> streamRag(String question) { return ragTemplate.stream(question) .map(chunk -> ServerSentEvent.builder(chunk).build()); } ``` --- #### 3. askWithMemory(String conversationId, String question) 带记忆的 RAG 问答 **签名**: ```java public String askWithMemory(String conversationId, String question) ``` **参数**: - `conversationId`: 会话ID - `question`: 用户问题 **返回**: 基于知识库的回答 **示例**: ```java String answer = ragTemplate.askWithMemory("session_001", "结合我之前的问题,再详细解释一下"); ``` --- #### 4. askWithConfig(String question, double similarityThreshold, int topK) 自定义检索参数的 RAG 问答 **签名**: ```java public String askWithConfig(String question, double similarityThreshold, int topK) ``` **参数**: - `question`: 用户问题 - `similarityThreshold`: 相似度阈值(0.0-1.0),越高越严格 - `topK`: 返回最相关的 K 个文档片段 **返回**: 基于知识库的回答 **示例**: ```java // 高精度模式: 只返回非常相关的内容 String answer = ragTemplate.askWithConfig(question, 0.9, 3); // 召回模式: 返回更多相关内容 String answer = ragTemplate.askWithConfig(question, 0.6, 10); ``` --- ## GraphTemplate API ### 类说明 `com.ccb.fintec.graph.template.GraphTemplate` 提供工作流编排能力,支持顺序、并行、路由、循环等模式。 ### 静态方法 #### 1. sequential(Node... nodes) 创建顺序工作流 **签名**: ```java public static SequentialWorkflow sequential(Node... nodes) ``` **参数**: - `nodes`: 按顺序执行的节点数组 **返回**: 顺序工作流实例 **示例**: ```java SequentialWorkflow workflow = GraphTemplate.sequential( GraphTemplate.node("清洗", text -> text.trim()), GraphTemplate.node("翻译", text -> translate(text)), GraphTemplate.node("总结", text -> summarize(text)) ); String result = workflow.execute(input); ``` --- #### 2. parallel(Node... nodes) 创建并行工作流 **签名**: ```java public static ParallelWorkflow parallel(Node... nodes) ``` **参数**: - `nodes`: 并行执行的节点数组 **返回**: 并行工作流实例 **示例**: ```java ParallelWorkflow workflow = GraphTemplate.parallel( GraphTemplate.node("情感分析", text -> sentiment(text)), GraphTemplate.node("关键词提取", text -> keywords(text)), GraphTemplate.node("分类", text -> classify(text)) ); List results = workflow.execute(input); ``` --- #### 3. routing() 创建路由工作流构建器 **签名**: ```java public static RoutingWorkflow routing() ``` **返回**: 路由工作流构建器 **示例**: ```java RoutingWorkflow workflow = GraphTemplate.routing() .addBranch("技术", Condition.of(ctx -> ((String)ctx).contains("技术")), GraphTemplate.node("技术回答", q -> techAnswer(q))) .addBranch("业务", Condition.of(ctx -> ((String)ctx).contains("业务")), GraphTemplate.node("业务回答", q -> businessAnswer(q))) .setDefault(GraphTemplate.node("通用回答", q -> generalAnswer(q))); String result = workflow.execute(question); ``` --- #### 4. loop(Node node, Condition condition, int maxIterations) 创建循环工作流 **签名**: ```java public static LoopWorkflow loop(Node node, Condition condition, int maxIterations) ``` **参数**: - `node`: 要循环执行的节点 - `condition`: 继续循环的条件(返回 true 则继续) - `maxIterations`: 最大迭代次数(防止死循环) **返回**: 循环工作流实例 **示例**: ```java LoopWorkflow workflow = GraphTemplate.loop( GraphTemplate.node("优化", text -> optimize(text)), Condition.of(result -> !isSatisfactory((String)result)), 5 // 最多迭代5次 ); String result = workflow.execute(initialText); ``` --- #### 5. node(String name, Function function) 创建工作流节点 **签名**: ```java public static Node node(String name, Function function) ``` **参数**: - `name`: 节点名称(用于调试和日志) - `function`: 节点执行逻辑 **返回**: 节点实例 **示例**: ```java Node node = GraphTemplate.node( "数据转换", data -> data.toUpperCase() ); ``` --- ## 配置项说明 ### 核心配置 (app.ai.*) #### 安全防护 (app.ai.safety.*) | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `enabled` | Boolean | true | 是否启用安全防护 | | `block-keywords` | List | [] | 敏感词列表 | **示例**: ```yaml app: ai: safety: enabled: true block-keywords: - 暴力 - 色情 - 赌博 ``` **功能说明**: - 双向检查:拦截请求和响应中的敏感内容 - 大小写不敏感:自动转小写匹配 - 发现敏感词时抛出 `AiException` 异常 --- #### 限流配置 (app.ai.rate-limit.*) | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `max-requests-per-minute` | Integer | 60 | 每分钟最大请求数 | **示例**: ```yaml app: ai: rate-limit: max-requests-per-minute: 100 ``` --- #### 重试策略 (app.ai.retry.*) | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `enabled` | Boolean | true | 是否启用重试 | | `max-attempts` | Integer | 3 | 最大重试次数 | | `backoff-ms` | Long | 1000 | 重试间隔(毫秒) | **示例**: ```yaml app: ai: retry: enabled: true max-attempts: 5 backoff-ms: 2000 ``` **功能说明**: - 自动处理网络波动、临时故障 - 记录重试日志,方便问题排查 - 支持固定退避时间 --- ### Spring AI 配置 (spring.ai.*) #### OpenAI 配置 | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `spring.ai.openai.api-key` | String | - | API Key | | `spring.ai.openai.base-url` | String | https://api.openai.com/v1 | API 地址 | | `spring.ai.openai.chat.options.model` | String | gpt-3.5-turbo | 模型名称 | | `spring.ai.openai.chat.options.temperature` | Double | 0.7 | 温度参数(0-1) | | `spring.ai.openai.chat.options.max-tokens` | Integer | - | 最大输出 Token 数 | **示例**: ```yaml spring: ai: openai: api-key: ${OPENAI_API_KEY} base-url: https://api.openai.com/v1 chat: options: model: gpt-4-turbo temperature: 0.8 max-tokens: 2048 ``` --- #### Ollama 配置(本地模型) | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `spring.ai.ollama.base-url` | String | http://localhost:11434 | Ollama 地址 | | `spring.ai.ollama.chat.options.model` | String | llama3 | 模型名称 | **示例**: ```yaml spring: ai: ollama: base-url: http://localhost:11434 chat: options: model: qwen:7b ``` --- #### 通义千问配置 | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `spring.ai.dashscope.api-key` | String | - | API Key | | `spring.ai.dashscope.chat.options.model` | String | qwen-plus | 模型名称 | **示例**: ```yaml spring: ai: dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-max ``` --- ## 数据类型参考 ### Node 接口 ```java @FunctionalInterface public interface Node { O execute(I input); default String getName() { return this.getClass().getSimpleName(); } static Node of(String name, Function function) { return new SimpleNode<>(name, function); } } ``` --- ### Condition 接口 ```java @FunctionalInterface public interface Condition { boolean evaluate(Object context); static Condition of(Predicate predicate) { return predicate::test; } } ```