4. 框架与技术栈
构建生产级代理需要选择合适的框架并理解如何实现核心模式。本节比较主要框架并为 Java/Spring Boot 开发者提供详细的 Spring AI 实现指南。
4.1 框架比较
主要框架概述
比较矩阵
| 框架 | 语言 | 成熟度 | 多代理 | 有状态 | 最佳用途 |
|---|---|---|---|---|---|
| Spring AI | Java | 增长中 | 基础 | 是 | 企业 Java |
| LangChain | Python | 成熟 | 基础 | 有限 | 快速原型开发 |
| LangGraph | Python | 增长中 | 优秀 | 是 | 复杂工作流 |
| Semantic Kernel | Python/C# | 成熟 | 良好 | 是 | 微软技术栈 |
| AutoGen | Python | 成熟 | 优秀 | 是 | 研究 |
| CrewAI | Python | 新 | 优秀 | 是 | 基于角色的代理 |
| LangChain4j | Java | 增长中 | 基础 | 是 | LangChain 的 Java 端口 |
功能比较
| 功能 | Spring AI | LangGraph | Semantic Kernel | AutoGen |
|---|---|---|---|---|
| 工具调用 | ✅ 原生 | ✅ 原生 | ✅ 原生 | ✅ 原生 |
| 内存管理 | ✅ 强大 | ✅ 强大 | ✅ 良好 | ✅ 基础 |
| 多代理 | ⚠️ 基础 | ✅ 优秀 | ✅ 良好 | ✅ 优秀 |
| 状态持久化 | ✅ 是 | ✅ 优秀 | ✅ 良好 | ✅ 基础 |
| 可观测性 | ✅ Spring Boot Actuator | ✅ LangSmith | ✅ 遥测 | ⚠️ 基础 |
| 企业支持 | ✅ 优秀 | ⚠️ 有限 | ✅ 良好 | ⚠️ 有限 |
4.2 Spring AI 深入讲解
Spring AI 为构建代理系统的 Java/Spring Boot 开发者提供了最无缝的体验。
架构
项目设置
依赖项 (build.gradle)
dependencies {
// Spring AI OpenAI
implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter:1.0.0'
// Spring AI MCP
implementation 'org.springframework.ai:spring-ai-mcp-spring-boot-starter:1.0.0'
// Spring AI Vector Store (PostgreSQL + pgvector)
implementation 'org.springframework.ai:spring-ai-pgvector-store-spring-boot-starter:1.0.0'
// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// 环境变量 (Doppler 集成)
developmentOnly 'io.github.c-d-m:spring-boot-doppler:0.1.0'
}
配置 (application.yml)
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4-turbo
temperature: 0.7
mcp:
servers:
- name: filesystem
transport:
type: stdio
command: npx
args:
- -y
- "@modelcontextprotocol/server-filesystem"
- /allowed/path
vectorstore:
pgvector:
dimension: 1536
distance-type: cosine
index-type: ivfflat
# Actuator 用于可观测性
management:
endpoints:
web:
exposure:
include: health,metrics,httptrace
tracing:
sampling:
probability: 1.0
核心组件
1. ChatClient 配置
@Configuration
public class ChatClientConfig {
@Bean
public ChatClient chatClient(OpenAiChatModel model) {
return ChatClient.builder(model)
.defaultSystem("You are a helpful AI assistant with access to tools.")
.defaultOptions(OpenAiChatOptions.builder()
.model("gpt-4-turbo")
.temperature(0.7)
.build())
.build();
}
}
2. 工具定义
@Component
public class AgentTools {
@Autowired
private SearchService searchService;
@Autowired
private DatabaseService databaseService;
@Bean
public FunctionCallback searchTool() {
return FunctionCallback.builder()
.function("search_web", this::searchWeb)
.description("Search the web for current information")
.inputType(SearchRequest.class)
.build();
}
@Bean
public FunctionCallback databaseQueryTool() {
return FunctionCallback.builder()
.function("query_database", this::queryDatabase)
.description("Query the database for structured data")
.inputType(DatabaseQuery.class)
.build();
}
public record SearchRequest(
@Description("The search query string") String query,
@Description("Number of results to return") @DefaultValue("5") int numResults
) {}
public String searchWeb(SearchRequest request) {
return searchService.search(request.query(), request.numResults());
}
public record DatabaseQuery(
@Description("SQL query to execute") String sql
) {}
public String queryDatabase(DatabaseQuery query) {
return databaseService.executeQuery(query.sql());
}
}
3. 内存配置
@Configuration
public class MemoryConfig {
@Bean
public ChatMemory bufferMemory() {
return new MessageWindowChatMemory(10); // 最后 10 条消息
}
@Bean
public ChatMemory vectorMemory(VectorStore vectorStore) {
return new VectorStoreChatMemory(vectorStore);
}
@Bean
public VectorStore vectorStore(JdbcTemplate jdbcTemplate, EmbeddingModel embeddingModel) {
return new PgVectorStore(jdbcTemplate, embeddingModel);
}
}
完整代理实现
使用 Spring AI 的 ReAct 代理
@Service
public class ReactAgentService {
@Autowired
private ChatClient chatClient;
@Autowired
private List<FunctionCallback> tools;
@Autowired
private ChatMemory memory;
public String execute(String query, int maxIterations) {
AgentContext context = new AgentContext(query, memory);
for (int i = 0; i < maxIterations; i++) {
// 生成思考并决定行动
AgentResponse response = thinkAndAct(context);
// 检查代理是否想直接回答
if (response.isFinal()) {
return response.getContent();
}
// 执行工具
String toolResult = executeTool(response.getToolCall());
// 添加到上下文
context.addObservation(toolResult);
// 更新内存
memory.add(response.getMessage());
}
return "Max iterations reached";
}
private AgentResponse thinkAndAct(AgentContext context) {
return chatClient.prompt()
.messages(context.getMessages())
.functions(tools)
.call()
.entity(AgentResponse.class);
}
private String executeTool(ToolCall call) {
FunctionCallback tool = findTool(call.name());
return tool.call(call.arguments());
}
private FunctionCallback findTool(String name) {
return tools.stream()
.filter(t -> t.getName().equals(name))
.findFirst()
.orElseThrow();
}
}
REST 控制器
@RestController
@RequestMapping("/api/agents")
public class AgentController {
@Autowired
private ReactAgentService reactAgent;
@PostMapping("/chat")
public ResponseEntity<ChatResponse> chat(@RequestBody ChatRequest request) {
String response = reactAgent.execute(
request.getMessage(),
request.getMaxIterations()
);
return ResponseEntity.ok(new ChatResponse(response));
}
@PostMapping("/stream")
public Flux<String> chatStream(@RequestBody ChatRequest request) {
return reactAgent.executeStream(request.getMessage())
.map(chunk -> "data: " + chunk + "\n\n");
}
}