Spring AI 和 FastAPI+LangChain 哪个好?全维度对比与选型建议(后附实战案例)
Spring Boot+Vue+Spring AI vs Spring Boot+Vue+Python(FastAPI+LangChain):深度对比与后者的架构优势
随着大模型技术的普及,「Java业务后端+Vue前端+AI层」已成为企业级AI应用开发的主流架构范式。但在AI层的技术选型上,开发者往往面临两个核心方向:是用Spring AI无缝融入Java生态,还是用Python(FastAPI+LangChain) 独立构建AI服务?
本文将从架构设计、AI生态、开发效率、定制化能力、部署运维等维度进行深度对比,结合代码示例拆解后者的核心优势,帮你在技术选型时做出最适合的决策。
引言:为什么会有两种架构选择?
在企业级开发中,Spring Boot 凭借其成熟的生态、强大的事务管理、安全机制和企业级特性,几乎是业务后端的默认选择;Vue 则以其轻量、灵活、易上手的特点,成为前端开发的主流框架。这两者的组合,构成了AI应用的「业务基座」。
而AI层的选型分歧,本质上是**「Java生态的统一性」与「Python生态的AI能力丰富度」**之间的权衡:
- 选择Spring AI,意味着你可以用Java语言统一开发业务和AI逻辑,无需切换技术栈,依赖管理、部署运维都更简单;
- 选择Python(FastAPI+LangChain),则是将AI层独立为服务,充分利用Python在AI领域的生态优势,同时保持业务层的稳定。
接下来,我们先分别拆解两种架构的核心组成,再进行多维度的深度对比。
一、两种架构的核心组成与基础实现
1.1 架构一:Spring Boot + Vue + Spring AI
这是一个**「全Java技术栈」**的架构:Spring Boot负责业务逻辑、用户管理、数据库交互、权限控制;Vue负责前端交互;Spring AI作为Spring生态的原生组件,直接在Spring Boot中集成大模型能力。
核心组件
| 层级 | 技术选型 | 核心职责 |
|---|---|---|
| 前端 | Vue 3 + TypeScript + Element Plus | 用户界面、交互逻辑、状态管理 |
| 业务后端 | Spring Boot 3.x + Spring Data JPA/MyBatis Plus | 用户管理、业务流程、数据持久化、权限控制 |
| AI层 | Spring AI | 大模型调用、Prompt管理、简单的RAG(检索增强生成) |
基础代码示例:Spring AI实现简单对话
Spring AI提供了ChatClient抽象,让大模型调用像写Java代码一样自然:
// 1. 引入依赖(pom.xml)
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
// 2. 配置文件(application.yml)
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY:your-api-key}
chat:
options:
model: gpt-4o
temperature: 0.7
// 3. 业务代码实现
@RestController
@RequestMapping("/api/ai")
@RequiredArgsConstructor
public class SpringAIController {
private final ChatClient.Builder chatClientBuilder;
// 简单对话
@PostMapping("/chat")
public String chat(@RequestBody String userMessage) {
ChatClient chatClient = chatClientBuilder.build();
return chatClient.prompt()
.user(userMessage)
.call()
.content();
}
// 带Prompt模板的对话
@PostMapping("/chat-with-template")
public String chatWithTemplate(@RequestParam String language, @RequestBody String code) {
ChatClient chatClient = chatClientBuilder.build();
// 定义Prompt模板
PromptTemplate promptTemplate = new PromptTemplate("""
请用{language}语言解释以下代码的功能,并指出潜在问题:
{code}
""");
// 填充模板参数
Prompt prompt = promptTemplate.create(Map.of("language", language, "code", code));
return chatClient.prompt(prompt).call().content();
}
}
架构优势
- 技术栈统一:全Java开发,团队无需学习新语言,招聘、培训成本低;
- 依赖管理简单:Maven/Gradle统一管理所有依赖,无需处理Python的虚拟环境和依赖冲突;
- 部署运维方便:整个应用打包成一个JAR文件,直接运行即可,监控、日志都用Spring Boot的成熟方案;
- 与Spring生态无缝集成:可以直接使用Spring Security、Spring Transaction、Spring Cache等组件,AI逻辑可以轻松访问业务数据。
1.2 架构二:Spring Boot + Vue + Python(FastAPI + LangChain)
这是一个**「前后端分离+AI服务独立」的架构:Spring Boot依然负责核心业务逻辑,Vue负责前端,而AI层则用FastAPI构建独立的API服务,用LangChain**负责AI应用的编排(链、记忆、RAG、Agent等),两者通过HTTP/REST或gRPC通信。
核心组件
| 层级 | 技术选型 | 核心职责 |
|---|---|---|
| 前端 | Vue 3 + TypeScript + Element Plus | 用户界面、交互逻辑、状态管理 |
| 业务后端 | Spring Boot 3.x | 用户管理、业务流程、数据持久化、权限控制、调用AI服务 |
| AI服务层 | FastAPI + LangChain + LangGraph | 大模型编排、RAG、Agent、记忆管理、工具调用、向量数据库集成 |
| 基础设施 | 向量数据库(Chroma/Pinecone)、大模型(OpenAI/Anthropic) | 数据存储、模型能力 |
基础代码示例:FastAPI+LangChain实现对话服务
我们将AI层独立为服务,用FastAPI提供API,LangChain负责逻辑编排:
# 1. 依赖管理(requirements.txt)
fastapi==0.115.0
uvicorn==0.32.0
langchain==0.3.0
langchain-openai==0.2.0
langchain-core==0.3.0
python-dotenv==1.0.0
# 2. FastAPI服务实现(main.py)
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain.memory import ChatMessageHistory
from dotenv import load_dotenv
import os
# 加载配置
load_dotenv()
app = FastAPI(title="AI Service", version="1.0")
# 定义请求模型
class ChatRequest(BaseModel):
session_id: str
user_message: str
# 全局存储会话记忆(生产环境建议用Redis)
session_store = {}
def get_session_history(session_id: str) -> ChatMessageHistory:
if session_id not in session_store:
session_store[session_id] = ChatMessageHistory()
return session_store[session_id]
# 初始化LangChain组件
llm = ChatOpenAI(model="gpt-4o", temperature=0.7, api_key=os.getenv("OPENAI_API_KEY"))
# 定义带记忆的Prompt模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个专业的AI助手,用简洁、准确的语言回答用户问题。"),
MessagesPlaceholder(variable_name="history"),
("human", "{user_message}")
])
# 构建链
chain = prompt | llm | StrOutputParser()
# 给链添加会话记忆
chain_with_history = RunnableWithMessageHistory(
chain,
get_session_history,
input_messages_key="user_message",
history_messages_key="history"
)
# 提供API接口
@app.post("/api/ai/chat")
async def chat(request: ChatRequest):
try:
response = chain_with_history.invoke(
{"user_message": request.user_message},
config={"configurable": {"session_id": request.session_id}}
)
return {"response": response}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# 启动服务:uvicorn main:app --reload --port 8001
Spring Boot调用FastAPI的代码示例
业务后端通过RestTemplate或WebClient调用AI服务:
// Spring Boot中调用FastAPI的AI服务
@RestController
@RequestMapping("/api/business")
@RequiredArgsConstructor
public class BusinessController {
private final WebClient.Builder webClientBuilder;
@PostMapping("/chat")
public Mono<String> businessChat(@RequestBody ChatRequest request) {
// 先进行业务逻辑处理(比如权限校验、用户信息查询)
// 然后调用FastAPI的AI服务
return webClientBuilder.build()
.post()
.uri("http://localhost:8001/api/ai/chat")
.bodyValue(request)
.retrieve()
.bodyToMono(Map.class)
.map(map -> (String) map.get("response"));
}
// 请求模型
@Data
public static class ChatRequest {
private String sessionId;
private String userMessage;
}
}
架构特点
- 职责分离:业务层和AI层完全解耦,各自独立开发、部署、扩展;
- AI能力最大化:充分利用Python的AI生态,实现复杂的AI应用;
- 技术栈灵活:业务层保持Java的稳定性,AI层享受Python的生态红利。
二、核心维度深度对比:为什么后者往往是更优选择?
从简单的对话应用来看,两种架构都能实现,但当AI需求变得复杂(比如需要RAG、Agent、自定义工具、多模型编排)时,Spring Boot+Vue+Python(FastAPI+LangChain) 的优势就会凸显出来。我们从7个核心维度进行对比。
2.1 AI生态丰富度:Python是绝对的王者
AI应用开发的核心,不仅是调用大模型,更是**「模型+工具+数据+编排」**的组合。在这方面,Python的生态丰富度是Java无法比拟的。
对比表
| 生态类别 | Python(FastAPI+LangChain) | Spring AI |
|---|---|---|
| 大模型支持 | 几乎所有主流模型都有Python SDK:OpenAI、Anthropic、Google Gemini、Meta Llama 3、Mistral、通义千问、文心一言等;Hugging Face Transformers可以直接加载开源模型 | 支持主流模型,但更新速度慢于Python;开源模型的集成相对麻烦 |
| 向量数据库 | LangChain原生支持Chroma、Pinecone、Weaviate、Milvus、Qdrant、PGVector等几乎所有主流向量数据库,集成代码只需几行 | 支持部分向量数据库(如Pinecone、Redis),但支持的数量和功能丰富度远不如LangChain |
| AI编排框架 | LangChain、LangGraph、LlamaIndex、Haystack等,提供链、记忆、Agent、RAG等全场景组件 | 有基础的Prompt模板和ChatClient,但复杂编排能力较弱 |
| 工具库 | 可以调用Python的所有库:数学计算(NumPy/SciPy)、数据处理(Pandas)、文档解析(PyPDF2、Unstructured)、代码执行(Python REPL)等 | 只能调用Java库,很多AI领域的工具库没有Java对应实现 |
代码对比:RAG(检索增强生成)实现
RAG是企业级AI应用的核心功能,我们看两种架构的实现复杂度:
Python+LangChain实现RAG(简洁、功能全):
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
# 1. 加载文档
loader = PyPDFLoader("企业知识库.pdf")
documents = loader.load()
# 2. 文档分割(LangChain提供多种分割策略)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
separators=["\n\n", "\n", "。", "!", "?", " ", ""]
)
split_docs = text_splitter.split_documents(documents)
# 3. 存入向量数据库
embeddings = OpenAIEmbeddings()
vector_store = Chroma.from_documents(split_docs, embeddings, persist_directory="./chroma_db")
# 4. 构建RAG链
llm = ChatOpenAI(model="gpt-4o")
rag_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vector_store.as_retriever(search_kwargs={"k": 3}),
return_source_documents=True
)
# 5. 调用RAG
result = rag_chain.invoke("公司的年假政策是什么?")
print("回答:", result["result"])
print("参考文档:", [doc.page_content for doc in result["source_documents"]])
Spring AI实现RAG(功能基础,定制化难):
// Spring AI的RAG实现相对基础
@Service
@RequiredArgsConstructor
public class SpringAIRAGService {
private final VectorStore vectorStore;
private final ChatClient.Builder chatClientBuilder;
public String ragChat(String userMessage) {
// 1. 检索相关文档
List<Document> docs = vectorStore.similaritySearch(SearchRequest.query(userMessage).withTopK(3));
String context = docs.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n\n"));
// 2. 手动构建Prompt
String prompt = """
请根据以下参考文档回答用户问题,如果参考文档中没有相关信息,请说"我不知道"。
参考文档:
{context}
用户问题:{userMessage}
""".replace("{context}", context).replace("{userMessage}", userMessage);
// 3. 调用大模型
ChatClient chatClient = chatClientBuilder.build();
return chatClient.prompt().user(prompt).call().content();
}
}
对比结论:
- LangChain的RAG提供了多种链类型(
stuff、map_reduce、refine、map_rerank),可以处理不同长度的文档; - LangChain的文档分割器更丰富,支持按语义、按字符、按递归等多种策略;
- LangChain的检索器支持重排序(Rerank)、过滤(Filter)等高级功能,Spring AI的基础实现没有这些。
2.2 开发灵活性与定制化能力:Python的动态语言优势明显
AI应用开发是一个快速迭代、不断试错的过程,需要频繁调整Prompt、修改链的结构、添加自定义工具。在这方面,Python的动态语言特性和LangChain的模块化设计,提供了远超Spring AI的灵活性。
1. 自定义工具的实现对比
Agent(智能代理)是AI应用的高级功能,需要让大模型调用自定义工具(比如查询数据库、调用业务API、执行代码)。
Python+LangChain自定义工具(简洁、直观):
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
# 1. 定义自定义工具(用@tool装饰器,几行代码搞定)
@tool
def query_employee_annual_leave(employee_id: str) -> str:
"""查询员工的年假余额,输入员工ID"""
# 这里可以调用Spring Boot的业务API,或者直接查询数据库
return f"员工{employee_id}的年假余额为:5天"
@tool
def query_company_policy(policy_type: str) -> str:
"""查询公司政策,输入政策类型(如"年假"、"病假"、"社保")"""
policy_db = {
"年假": "员工入职满1年享有5天年假,每多1年增加1天,上限15天。",
"病假": "员工每月享有1天带薪病假,需提供医院证明。"
}
return policy_db.get(policy_type, "未找到相关政策")
# 2. 构建Agent
tools = [query_employee_annual_leave, query_company_policy]
llm = ChatOpenAI(model="gpt-4o", temperature=0)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个专业的HR助手,用工具查询信息后回答用户问题。"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}")
])
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 3. 调用Agent
result = agent_executor.invoke({"input": "我是员工E001,我的年假有多少?公司年假政策是什么?"})
print(result["output"])
Spring AI自定义工具(代码量多,类型繁琐):
Spring AI也支持工具调用,但需要定义类、实现接口,代码量明显更多:
// 1. 定义工具类
@Component
public class HRTools {
// 用@Tool注解标记工具
@Tool("查询员工的年假余额,输入员工ID")
public String queryEmployeeAnnualLeave(String employeeId) {
return "员工" + employeeId + "的年假余额为:5天";
}
@Tool("查询公司政策,输入政策类型")
public String queryCompanyPolicy(String policyType) {
Map<String, String> policyDb = Map.of(
"年假", "员工入职满1年享有5天年假...",
"病假", "员工每月享有1天带薪病假..."
);
return policyDb.getOrDefault(policyType, "未找到相关政策");
}
}
// 2. 构建Agent
@Service
@RequiredArgsConstructor
public class SpringAIAgentService {
private final HRTools hrTools;
private final ChatClient.Builder chatClientBuilder;
public String agentChat(String userMessage) {
ChatClient chatClient = chatClientBuilder.build();
return chatClient.prompt()
.user(userMessage)
.tools(hrTools) // 注入工具
.call()
.content();
}
}
2. 复杂编排的灵活性
LangChain的LangGraph可以构建复杂的状态图(State Graph),实现多步骤、有分支、有循环的AI流程(比如先检索、再判断、再生成、再反思),这是Spring AI目前无法做到的。
LangGraph实现复杂编排(示例:反思Agent):
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
from langchain_openai import ChatOpenAI
# 定义状态
class AgentState(TypedDict):
messages: List[BaseMessage]
reflection_count: int
llm = ChatOpenAI(model="gpt-4o")
# 定义节点:生成回答
def generate_node(state: AgentState):
response = llm.invoke(state["messages"])
return {"messages": [response], "reflection_count": state["reflection_count"]}
# 定义节点:反思回答
def reflect_node(state: AgentState):
reflection_prompt = """请反思以下回答是否准确、完整,如果有问题请指出。
回答:{answer}"""
reflection = llm.invoke(reflection_prompt.format(answer=state["messages"][-1].content))
return {"messages": state["messages"] + [reflection], "reflection_count": state["reflection_count"] + 1}
# 定义条件边:判断是否需要继续反思
def should_continue(state: AgentState):
if state["reflection_count"] >= 2:
return END
else:
return "reflect"
# 构建图
workflow = StateGraph(AgentState)
workflow.add_node("generate", generate_node)
workflow.add_node("reflect", reflect_node)
workflow.set_entry_point("generate")
workflow.add_conditional_edges("generate", should_continue, {"reflect": "reflect", END: END})
workflow.add_edge("reflect", "generate")
# 编译并运行
app = workflow.compile()
result = app.invoke({"messages": [HumanMessage(content="解释一下量子计算")], "reflection_count": 0})
print(result["messages"][-1].content)
这种复杂的、有状态的编排,用Spring AI很难实现,即使实现了,代码也会非常冗长。
2.3 模型支持与更新速度:Python永远走在最前面
大模型技术迭代非常快,几乎每周都有新模型、新功能发布。在这方面,Python的SDK更新速度是最快的,而Spring AI往往需要等待社区或官方适配。
典型场景对比
| 新模型/新功能 | Python SDK更新时间 | Spring AI适配时间 |
|---|---|---|
| OpenAI GPT-4o | 发布当天 | 3-7天 |
| Anthropic Claude 3.5 Sonnet | 发布当天 | 5-10天 |
| OpenAI Structured Outputs(结构化输出) | 发布当天 | 2-4周 |
| OpenAI o1(推理模型) | 发布当天 | 待定 |
如果你想第一时间用上最新的模型和功能,Python是唯一的选择。
2.4 部署与扩展:独立服务的架构优势
很多人认为Spring AI的部署更简单,但实际上,AI服务独立部署的架构,在扩展性和资源利用上更有优势:
1. 资源隔离与弹性扩展
- AI服务往往需要GPU:比如你要部署开源模型(Llama 3、Qwen),或者做大量的文档嵌入,GPU是必须的。而Spring Boot业务服务只需要CPU。如果用Spring AI,你不得不把整个应用部署在GPU服务器上,造成资源浪费;
- 独立扩展:AI服务和业务服务可以独立扩展——如果AI请求多,就增加FastAPI的实例;如果业务请求多,就增加Spring Boot的实例,互不影响。
2. Docker Compose部署示例
独立部署并不复杂,用Docker Compose可以一键启动所有服务:
version: '3.8'
services:
# Spring Boot业务后端
backend:
build: ./backend
ports:
- "8080:8080"
environment:
- AI_SERVICE_URL=http://ai-service:8001
depends_on:
- ai-service
# FastAPI AI服务
ai-service:
build: ./ai-service
ports:
- "8001:8001"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
volumes:
- ./chroma_db:/app/chroma_db # 挂载向量数据库
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu] # AI服务可以单独用GPU
# Vue前端
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
# 向量数据库
chroma:
image: chromadb/chroma:latest
ports:
- "8000:8000"
2.5 人才储备与社区支持:Python AI人才更多,社区更活跃
- 人才储备:现在市场上懂LangChain、FastAPI、大模型开发的Python开发者,远多于懂Spring AI的Java开发者;
- 社区支持:
- Python的AI社区非常活跃,GitHub上LangChain的Star数超过10万,教程、博客、问题解答随处可见;
- Spring AI还在发展中,社区资源相对较少,遇到问题可能需要自己看源码解决。
三、后者(Spring Boot+Vue+Python)的核心优势总结
经过前面的对比,我们可以将后者的优势总结为以下6点:
- AI生态绝对领先:可以使用所有主流的大模型、向量数据库、AI工具库,功能最全;
- 开发灵活性高:动态语言+模块化设计,快速迭代、定制化简单;
- 复杂AI应用支持好:LangChain+LangGraph可以轻松实现RAG、Agent、复杂编排等高级功能;
- 模型更新最快:第一时间用上最新的模型和功能;
- 架构更合理:业务层和AI层解耦,独立部署、独立扩展,资源利用更高效;
- 人才与社区支持好:更容易招到合适的人才,遇到问题更容易找到解决方案。
四、如何选择?适用场景分析
当然,没有最好的架构,只有最适合的架构。我们可以根据以下场景选择:
选择Spring Boot+Vue+Spring AI的场景
- 团队全是Java开发者,没有Python基础,且学习成本过高;
- AI需求非常简单,只是调用大模型进行简单对话,不需要RAG、Agent等高级功能;
- 项目周期短、规模小,不想维护多个服务;
- 对模型更新速度要求不高,不需要第一时间用最新模型。
选择Spring Boot+Vue+Python(FastAPI+LangChain)的场景
- AI需求复杂,需要RAG、Agent、自定义工具、多模型编排;
- 想第一时间用上最新的模型和功能;
- AI服务需要GPU,或者需要独立扩展;
- 团队有Python开发者,或者愿意学习Python;
- 项目是长期迭代的企业级应用,需要灵活的架构和丰富的生态。
五、实战案例:智能客服系统的完整实现
为了让大家更直观地理解,我们用一个智能客服系统的案例,展示后者的完整实现。
需求描述
- 业务功能:用户管理、订单查询、知识库管理(Spring Boot实现);
- AI功能:基于知识库的RAG、调用订单查询工具、会话记忆(FastAPI+LangChain实现);
- 前端:Vue聊天界面。
核心代码实现
1. Spring Boot业务端:提供订单查询API
// 订单实体
@Entity
@Data
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String orderNo;
private String userId;
private String status; // 待支付、待发货、已发货、已完成
private BigDecimal amount;
}
// 订单查询API
@RestController
@RequestMapping("/api/business/orders")
@RequiredArgsConstructor
public class OrderController {
private final OrderRepository orderRepository;
@GetMapping("/{orderNo}")
public Order getOrder(@PathVariable String orderNo) {
return orderRepository.findByOrderNo(orderNo)
.orElseThrow(() -> new RuntimeException("订单不存在"));
}
}
2. FastAPI AI端:实现带工具的RAG Agent
from fastapi import FastAPI
from pydantic import BaseModel
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.tools import tool
from langchain.memory import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
import requests
import os
app = FastAPI()
# 1. 定义工具:调用Spring Boot的订单查询API
@tool
def query_order(order_no: str) -> str:
"""查询订单信息,输入订单号"""
try:
response = requests.get(f"http://backend:8080/api/business/orders/{order_no}")
if response.status_code == 200:
order = response.json()
return f"订单{order_no}的信息:状态{order['status']},金额{order['amount']}元"
else:
return "未找到该订单"
except Exception as e:
return f"查询订单失败:{str(e)}"
# 2. 加载向量数据库(知识库)
embeddings = OpenAIEmbeddings()
vector_store = Chroma(persist_directory="./chroma_db", embedding_function=embeddings)
retriever = vector_store.as_retriever(search_kwargs={"k": 3})
@tool
def query_knowledge_base(question: str) -> str:
"""查询知识库,输入用户问题"""
docs = retriever.invoke(question)
return "\n\n".join([doc.page_content for doc in docs])
# 3. 构建Agent
tools = [query_order, query_knowledge_base]
llm = ChatOpenAI(model="gpt-4o", temperature=0.7)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个智能客服,用知识库的信息回答用户问题,如果用户问订单,用工具查询。"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}")
])
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 4. 会话记忆
session_store = {}
def get_session_history(session_id: str):
if session_id not in session_store:
session_store[session_id] = ChatMessageHistory()
return session_store[session_id]
agent_with_history = RunnableWithMessageHistory(
agent_executor,
get_session_history,
input_messages_key="input",
history_messages_key="history",
output_messages_key="output"
)
# 5. API接口
class ChatRequest(BaseModel):
session_id: str
user_message: str
@app.post("/api/ai/chat")
async def chat(request: ChatRequest):
result = agent_with_history.invoke(
{"input": request.user_message},
config={"configurable": {"session_id": request.session_id}}
)
return {"response": result["output"]}
3. Vue前端:聊天界面
<template>
<div class="chat-container">
<div class="message-list" ref="messageList">
<div v-for="(msg, index) in messages" :key="index" :class="['message', msg.role]">
{{ msg.content }}
</div>
</div>
<div class="input-area">
<el-input v-model="inputMessage" @keyup.enter="sendMessage" placeholder="请输入问题..." />
<el-button type="primary" @click="sendMessage">发送</el-button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue'
import axios from 'axios'
const messageList = ref<HTMLElement>()
const messages = ref<{ role: string; content: string }[]>([])
const inputMessage = ref('')
const sessionId = ref('session-' + Date.now())
const sendMessage = async () => {
if (!inputMessage.value.trim()) return
messages.value.push({ role: 'user', content: inputMessage.value })
const userMsg = inputMessage.value
inputMessage.value = ''
try {
const res = await axios.post('/api/business/chat', {
sessionId: sessionId.value,
userMessage: userMsg
})
messages.value.push({ role: 'assistant', content: res.data })
} catch (e) {
messages.value.push({ role: 'assistant', content: '抱歉,服务出错了' })
}
await nextTick()
messageList.value?.scrollTo(0, messageList.value.scrollHeight)
}
</script>
<style scoped>
.chat-container {
width: 600px;
margin: 50px auto;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.message-list {
height: 400px;
overflow-y: auto;
padding: 20px;
}
.message {
margin-bottom: 10px;
padding: 10px;
border-radius: 4px;
}
.message.user {
background-color: #e3f2fd;
text-align: right;
}
.message.assistant {
background-color: #f5f5f5;
}
.input-area {
display: flex;
padding: 20px;
border-top: 1px solid #ddd;
}
.input-area .el-input {
flex: 1;
margin-right: 10px;
}
</style>
结语:架构选择的本质是「需求与能力的匹配」
回到开头的问题,这两种架构没有绝对的对错,只有「适合」与「不适合」。
- 如果你需要快速上线一个简单的AI应用,团队全是Java开发者,Spring AI是很好的选择;
- 如果你要构建一个复杂的、长期迭代的企业级AI应用,需要RAG、Agent、灵活的定制化,或者想第一时间用上最新的AI技术,Spring Boot+Vue+Python(FastAPI+LangChain) 几乎是必然的选择。
互动讨论
在你的项目中,你用的是哪种架构?遇到了哪些问题?你觉得后者还有哪些优势?欢迎在评论区留言分享,我们一起交流讨论!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)