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的代码示例

业务后端通过RestTemplateWebClient调用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提供了多种链类型(stuffmap_reducerefinemap_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点:

  1. AI生态绝对领先:可以使用所有主流的大模型、向量数据库、AI工具库,功能最全;
  2. 开发灵活性高:动态语言+模块化设计,快速迭代、定制化简单;
  3. 复杂AI应用支持好:LangChain+LangGraph可以轻松实现RAG、Agent、复杂编排等高级功能;
  4. 模型更新最快:第一时间用上最新的模型和功能;
  5. 架构更合理:业务层和AI层解耦,独立部署、独立扩展,资源利用更高效;
  6. 人才与社区支持好:更容易招到合适的人才,遇到问题更容易找到解决方案。

四、如何选择?适用场景分析

当然,没有最好的架构,只有最适合的架构。我们可以根据以下场景选择:

选择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) 几乎是必然的选择。

互动讨论

在你的项目中,你用的是哪种架构?遇到了哪些问题?你觉得后者还有哪些优势?欢迎在评论区留言分享,我们一起交流讨论!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐