欢迎光临
我们一直在努力

Spring AI Alibaba 示例与实践 (简单版)

Spring AI Alibaba 实战示例与最佳实践

汇总 Spring AI Alibaba 框架的完整示例代码和最佳实践。


第一部分:核心对话示例

1.1 最简对话

@RestController
public class ChatController {
private final ChatClient chatClient;

public ChatController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}

@GetMapping("/chat")
public String chat(@RequestParam String query) {
return chatClient.prompt(query).call().content();
}
}

1.2 多轮对话

List<Message> messages = List.of(
new SystemMessage("你是一个 Java 专家"),
new UserMessage("什么是 Spring Boot?"),
new AssistantMessage("Spring Boot 是…"),
new UserMessage("它有什么优势?")
);

Prompt prompt = new Prompt(messages);
ChatResponse response = chatModel.call(prompt);

1.3 流式响应

Flux<ChatResponse> responseStream = chatModel.stream(
new Prompt("解释 Spring Boot 自动配置")
);

responseStream.subscribe(chatResponse -> {
System.out.print(chatResponse.getResult().getOutput().getText());
});

1.4 带记忆的对话

@RestController
@RequestMapping("/advisor/memory")
public class ChatMemoryController {

private final ChatClient chatClient;
private final MessageWindowChatMemory chatMemory;

public ChatMemoryController(ChatClient.Builder builder, ChatMemoryRepository repository) {
this.chatMemory = MessageWindowChatMemory.builder()
.chatMemoryRepository(repository)
.maxMessages(100)
.build();

this.chatClient = builder
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
.build();
}

@GetMapping("/call")
public String call(@RequestParam String query, @RequestParam String conversationId) {
return chatClient.prompt(query)
.advisors(a -> a.param(CONVERSATION_ID, conversationId))
.call().content();
}

@GetMapping("/messages")
public List<Message> messages(@RequestParam String conversationId) {
return chatMemory.get(conversationId);
}
}


第二部分:ReactAgent 完整示例

2.1 基础配置

@Configuration
public class AgentConfiguration {

private final ChatModel chatModel;

@Bean
public ReactAgent reactAgent() throws GraphStateException {
return ReactAgent.builder()
.name("agent")
.description("This is a react agent")
.model(chatModel)
.saver(new MemorySaver())
.tools(
new FileReadTool().toolCallback(),
new FileWriteTool().toolCallback()
)
.hooks(HumanInTheLoopHook.builder()
.approvalOn("file_write", "Write File should be approved")
.build())
.interceptors(new LogToolInterceptor())
.build();
}
}

2.2 自定义工具

@Component
public class FileWriteTool implements BiFunction<FileWriteTool.Request, ToolContext, String> {

@Override
public ToolCallback toolCallback() {
return FunctionToolCallback.builder("file_write", this)
.description("Tool for write files")
.inputType(Request.class)
.build();
}

@Override
public String apply(Request request, ToolContext toolContext) {
try {
String safePath = Paths.get(System.getProperty("user.dir"))
.resolve(request.filePath).normalize().toString();
Files.writeString(Paths.get(safePath), request.content);
return "Successfully wrote to file: " + request.filePath;
} catch (IOException e) {
return "Error writing to file: " + e.getMessage();
}
}

@JsonClassDescription("Request for writing a file")
public record Request(
@JsonProperty(value = "file_path", required = true)
@JsonPropertyDescription("The path of the file to write")
String filePath,
@JsonProperty(value = "content", required = true)
@JsonPropertyDescription("The content to write to the file")
String content
) {}
}

2.3 结构化输出

// 定义输出格式类
public class ContactInfo {
private String name;
private String email;
private String phone;
// Getter 和 Setter
}

// 配置 Agent 使用结构化输出
ReactAgent agent = ReactAgent.builder()
.name("contact_extractor")
.model(chatModel)
.outputType(ContactInfo.class)
.build();

// 调用 Agent
AssistantMessage result = agent.call(
"提取联系人信息:张三,zhangsan@example.com,(555) 123-4567");
// 输出: {"name": "张三", "email": "zhangsan@example.com", "phone": "(555) 123-4567"}


第三部分:多智能体示例

3.1 研究团队(顺序执行)

@Configuration
public class ResearchTeamConfig {

@Bean
public ReactAgent researcher(ChatModel model) {
return ReactAgent.builder()
.name("researcher")
.model(model)
.systemPrompt("你是一个研究专家,负责收集和整理信息。")
.tools(new WebSearchTool(), new DocumentReaderTool())
.build();
}

@Bean
public ReactAgent analyst(ChatModel model) {
return ReactAgent.builder()
.name("analyst")
.model(model)
.systemPrompt("你是一个分析专家,负责分析研究数据并提取洞察。")
.build();
}

@Bean
public ReactAgent writer(ChatModel model) {
return ReactAgent.builder()
.name("writer")
.model(model)
.systemPrompt("你是一个写作专家,负责将分析结果整理成报告。")
.build();
}

@Bean
public SequentialAgent researchPipeline(ReactAgent researcher,
ReactAgent analyst,
ReactAgent writer) {
return SequentialAgent.builder()
.name("research-pipeline")
.addAgent(researcher)
.addAgent(analyst)
.addAgent(writer)
.build();
}
}

3.2 并行执行

ParallelAgent parallel = ParallelAgent.builder()
.name("multi-research")
.addAgent(techResearchAgent)
.addAgent(marketResearchAgent)
.addAgent(competitorResearchAgent)
.aggregator(results -> String.join("\\n\\n", results))
.build();

String result = parallel.call("分析AI市场趋势");

3.3 路由选择

RoutingAgent router = RoutingAgent.builder()
.name("support-router")
.router((input, agents) -> {
if (input.contains("技术")) {
return "tech-support";
} else if (input.contains("账单")) {
return "billing-support";
}
return "general-support";
})
.addAgent("tech-support", techAgent)
.addAgent("billing-support", billingAgent)
.addAgent("general-support", generalAgent)
.build();

3.4 循环执行

LoopAgent loop = LoopAgent.builder()
.name("refinement-loop")
.agent(refinementAgent)
.maxIterations(5)
.terminationCondition((input, output) -> {
return output.contains("完成") || output.contains("满意");
})
.build();


第四部分:RAG Agent 示例

4.1 知识检索工具

@Component
public class KnowledgeRetrievalTool implements BiFunction<Request, ToolContext, String> {

private final SimpleVectorStore vectorStore;

public KnowledgeRetrievalTool(EmbeddingModel embeddingModel) {
this.vectorStore = SimpleVectorStore.builder(embeddingModel).build();
}

@PostConstruct
void initKnowledgeBase() {
for (String url : knowledgeSourceUrls) {
JsoupDocumentReader reader = new JsoupDocumentReader(url);
List<Document> documents = reader.get();
TokenTextSplitter splitter = new TokenTextSplitter();
vectorStore.add(splitter.apply(documents));
}
}

@Override
public String apply(Request request, ToolContext toolContext) {
SearchRequest searchRequest = SearchRequest.builder()
.query(request.query())
.topK(request.topK() != null ? request.topK() : 4)
.build();

List<Document> documents = vectorStore.similaritySearch(searchRequest);

return documents.stream()
.map(doc -> "—\\n" + doc.getFormattedContent() + "\\n—")
.collect(Collectors.joining("\\n\\n"));
}

public ToolCallback toolCallback() {
return FunctionToolCallback.builder("knowledge_retrieval", this)
.description("Retrieves relevant information from the knowledge base")
.inputType(Request.class)
.build();
}

public record Request(
@JsonProperty(value = "query", required = true)
String query,
@JsonProperty(value = "top_k")
Integer topK
) {}
}

4.2 RAG Agent 配置

@Configuration
public class RagAgentConfiguration {

@Bean
public ReactAgent ragAgent(ChatModel model, EmbeddingModel embeddingModel) {
KnowledgeRetrievalTool knowledgeTool = new KnowledgeRetrievalTool(embeddingModel);

return ReactAgent.builder()
.name("rag-agent")
.description("你是一个知识库问答助手,使用知识检索工具回答问题。")
.model(model)
.tools(knowledgeTool.toolCallback())
.saver(new MemorySaver())
.build();
}
}


第五部分:SQL Agent 示例

@Configuration
public class SqlAgentConfiguration {

private final ChatModel chatModel;
private final JdbcTemplate jdbcTemplate;

@Bean
public ReactAgent sqlAgent() throws GraphStateException {
return ReactAgent.builder()
.name("sql-agent")
.description("""
You are an agent designed to interact with a SQL database.
DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.).
Only SELECT queries are allowed.

Remember to:
1. First call list_tables
2. Then call get_schema
3. Then call check_query
4. Finally call execute_query
""")
.model(chatModel)
.tools(
new ListTablesTool(jdbcTemplate).toolCallback(),
new GetSchemaTool(jdbcTemplate).toolCallback(),
new QueryCheckerTool().toolCallback(),
new ExecuteQueryTool(jdbcTemplate).toolCallback()
)
.build();
}
}


第六部分:Voice Agent 示例

@Configuration
public class VoiceAgentConfiguration {

@Bean
public ReactAgent voiceReactAgent(ChatModel chatModel,
BookingTool bookingTool,
FlightChangeTool flightChangeTool) {
return ReactAgent.builder()
.name("voice-assistant")
.description("""
你是一个专业的航空公司语音助手。

你的能力:
1. 查询航班预订详情
2. 更改航班日期

重要输出规则:
– 只用纯文本,不要用 Markdown、列表符号或表情符号
– 保持回复简短,最多2-3句话
– 用自然口语化的中文回复,像电话交流一样
""")
.model(chatModel)
.saver(new MemorySaver())
.tools(bookingTool.toolCallback(), flightChangeTool.toolCallback())
.build();
}
}


第七部分:工作流示例

7.1 StateGraph 配置

@Configuration
public class GraphConfiguration {

@Bean
public CompiledGraph workflowGraph() {
StateGraph stateGraph = new StateGraph(OverAllState.class);

// 添加节点
stateGraph.addNode("node1", new ProcessNode());
stateGraph.addNode("node2", new TransformNode());
stateGraph.addNode("node3", new OutputNode());

// 添加边
stateGraph.addEdge(START, "node1");
stateGraph.addEdge("node1", "node2");
stateGraph.addEdge("node2", "node3");
stateGraph.addEdge("node3", END);

return stateGraph.compile();
}
}

7.2 条件边

stateGraph.addConditionalEdge("detectUpgrade",
new DetectUpgradeDispatcher(),
Map.of(
"upgrade", "upgrade",
"continue", "generateReply",
"end", END
));


第八部分:最佳实践

8.1 工具设计

  • 职责单一:每个工具专注单一功能
  • 描述清晰:提供准确的工具描述和参数说明
  • 错误处理:优雅处理异常,返回友好错误信息
  • 安全控制:敏感操作添加审批机制
  • 8.2 Agent 设计

  • 系统提示词:明确角色和行为规范
  • 记忆管理:使用 MemorySaver 保持对话状态
  • 迭代控制:设置合理的迭代次数限制
  • 结构化输出:定义可预测的响应格式
  • 8.3 多智能体编排

    场景推荐模式
    简单流程 SequentialAgent
    独立任务 ParallelAgent
    条件分支 RoutingAgent
    迭代优化 LoopAgent

    8.4 RAG 优化

  • 文档处理:chunk大小500-1000 tokens,保持适当overlap
  • 检索优化:使用混合检索提高召回,实施重排序提高精度
  • 生成优化:提供清晰的上下文格式,要求标注来源
  • 8.5 错误处理

  • 设置超时和重试
  • 实现降级策略
  • 记录执行日志
  • 使用拦截器统一处理

  • 第九部分:完整配置

    spring:
    application:
    name: springaialibabademo

    ai:
    dashscope:
    api-key: ${AI_DASHSCOPE_API_KEY}
    chat:
    options:
    model: qwenmax
    temperature: 0.7
    max-tokens: 2000
    embedding:
    options:
    model: textembeddingv3

    vectorstore:
    pgvector:
    dimensions: 1536
    index-type: hnsw

    memory:
    redis:
    host: localhost
    port: 6379
    timeout: 5000

    # RAG 配置
    rag:
    knowledge:
    sources:
    https://java2ai.com/docs/
    chunk-size: 500
    chunk-overlap: 50


    第十部分:依赖配置

    <dependencies>
    <!– Spring AI Alibaba Agent Framework –>
    <dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-agent-framework</artifactId>
    <version>1.1.2.0</version>
    </dependency>

    <!– Spring AI Alibaba DashScope Starter –>
    <dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    <version>1.1.2.0</version>
    </dependency>

    <!– Spring AI Alibaba Graph –>
    <dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-graph</artifactId>
    <version>1.1.2.0</version>
    </dependency>

    <!– Redis (可选) –>
    <dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    </dependency>

    <!– JDBC (可选) –>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    </dependencies>


    相关链接

    • 官方文档
    • GitHub
    • DashScope 控制台
    赞(0)
    未经允许不得转载:171主机测评 » Spring AI Alibaba 示例与实践 (简单版)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址