Agent从0到1落地实施:「小智伴」系统技术架构落地(二)

91 阅读8分钟

Agent从0到1落地实施:「小智伴」系统技术架构落地(二)

导语【AI大模型教程】

在上一篇文章中,我们聊到了“小智伴”产品的整体需求框架,主要由三大核心模块组成:智能AI面试****管理知识库管理以及答案智能分析

       那么本篇将从技术视角出发,从0到1,梳理“小智伴”智能助手在技术选型系统实现上的思路,带你一步步拆解这套AI系统的底层逻辑,掌握搭建一套agent产品的具体技术方案。

作为一名有着十年经验的后端开发者,我深刻体会到这样一个现象:当我们拿到需求时,很多程序员往往第一反应就是立刻开干,埋头写代码,而不是先去思考需求的完整性可行性有效性。这其实是一个非常危险的信号

       在真正的工程实践中,代码只是****结果思考才是起点。我们必须具备一定的产品思维,从业务、用户、技术多角度去审视需求,才能避免“做完才发现方向错了”的情况。

       其次,在动手之前,一定要先画出数据流向图。这一步能帮助我们更清晰地理解系统边界数据交互关系依赖路径,从而判断哪些技术方案最合适,怎样的设计能确保开发过程高效可控按时推进

《产品思维》

系****统数据流向图

技术选型

1

前端:vue3

2

后端:Python、FastAPI、LangChain、RAGFlow、LangGraph

3

其他:DeepSeek-v3模型、Mysql数据库、Es语义检索、Redis缓存、Embding向量化

4

工具:DrowIO画图

核心技术栈的职责

下面,我们来逐一拆解每个技术组件在架构中的角色。

**1. 前端:**Vue3 - 打造轻盈交互的界面

职责:负责用户与「小智伴」的所有交互。包括聊天界面、文件上传、设置管理等。

**2. 后端:**FastAPI - 构建高性能的API枢纽

职责:作为系统的网关,处理所有HTTP请求、用户认证、以及前后端数据格式的转换。

3. Agent核心:LangGraph - 智能决策的大脑

职责:这是「小智伴」的决策中枢。它负责理解用户输入,决定下一步该调用哪个工具,并整合工具返回的结果,最终生成给用户的回复。

4. 模型服务:DeepSeek-V3 - 核心的认知引擎

职责:作为底层的基础模型,为整个Agent提供语言理解、逻辑推理和内容生成能力。

5. 数据与知识层:RAGFlow + ES + MySQL - 赋予Agent记忆与知识,这是架构中最关键的数据处理部分,我们将其分为三个子系统:

MySQL

职责:存储结构化数据。如用户账户、聊天会话记录、工具调用日志等。

选型理由:关系型数据库,保证事务一致性,是业务数据的基石。

RAGFlow + Elasticsearch

职责:构建知识库与记忆系统。

工作流:

**价值:**这实现了我们需求中的“文档解析与问答”能力,让「小智伴」真正“读懂”你的资料。

知识注入:用户上传的PDF/Word文档,通过 RAGFlow 进行深度解析、切分、向量化。RAGFlow的强大之处在于能精准解析复杂格式的文档。

**知识存储:**向量化后的结果存入 Elasticsearch 的向量索引中。

**知识召回:**当用户提问时,Agent通过ES进行语义检索,找到最相关的文档片段作为上下文,再交给DeepSeek模型生成精准答案。

**6. 工具层:**网络检索 - 赋予Agent实时信息触手

职责:封装网络搜索API(如Serper、Google Search API),作为LangGraph的一个工具。

工作流:当用户询问“今天北京的天气”或“最新新闻”时,Agent会调用此工具获取实时信息,再整合进回复中。

技术拓展

在这里,我们使用了 Ragflow、LangGraph、向量化技术以及提示词。对于这些尚不熟悉的内容,我将在后续专门针对各个框架进行详细讲解。

Agent核心代码实现

01

后端接口入口,基于fastapi服务启动

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import os
from app.core.config import settings
from app.api.v1.api import api_router
from app.core.database import init_db
app = FastAPI(
title="小智伴 API",
description="个人智能助手系统 - 智能辅助面试、错题集收集、语音灵感检索、时间规划",
version="1.0.0",
openapi_url=f"{settings.API_V1_STR}/openapi.json"
)
# 设置CORS
app.add_middleware(
CORSMiddleware,
allow_origins=settings.BACKEND_CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 暂时注释复杂的API路由
app.include_router(api_router, prefix=settings.API_V1_STR)
@app.get("/")
asyncdefroot():
"""根路径健康检查"""
return JSONResponse(content={
"message": "小智伴 API 服务正在运行",
"status": "healthy",
"version": "1.0.0"
})
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
reload=True,
log_level="info"
)

02

核心请求生成试题的代码

from fastapi import APIRouter
from app.api.v1.endpoints import (
interview,
interview_management,
knowledge_base,
knowledge_base_simple,
error_book,
voice_inspiration,
time_planning,
auth,
exam_generator,
user_profile,
resume,
langgraph_exam
)
api_router = APIRouter()
# 用户认证相关路由
api_router.include_router(auth.router, prefix="/auth", tags=["认证"])
api_router.include_router(user_profile.router, prefix="/user", tags=["用户个人中心"])
# 智能辅助面试模块
api_router.include_router(interview.router, prefix="/interview", tags=["智能辅助面试"])
api_router.include_router(interview_management.router, prefix="/interview", tags=["面试管理"])
api_router.include_router(exam_generator.router, prefix="/interview", tags=["试题生成"])
api_router.include_router(langgraph_exam.router, prefix="/interview", tags=["LangGraph试题生成"])

03

LangGraph的试题生成代码

from fastapi.routing import APIRouter
from typing import List
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.database import get_db
from app.schemas.exam import (
ExamGenerationRequest,
ExamGenerationResponse,
GeneratedQuestion
)
from app.services.langgraph_service import langgraph_exam_service
from app.services.exam_service import ExamGenerationService
router: APIRouter = APIRouter()
@router.post("/generate-exam-langgraph", response_model=ExamGenerationResponse)
asyncdefgenerate_exam_questions_with_langgraph(
request: ExamGenerationRequest,
db: AsyncSession = Depends(get_db)
):
"""
使用LangGraph工作流生成考试试题并保存到数据库
Args:
request: 试题生成请求参数
db: 数据库会话
Returns:
生成的试题列表
"""
try:
questions = await langgraph_exam_service.generate_questions_with_workflow(request, db)
# 保存试题到数据库
exam_service = ExamGenerationService(db)
await exam_service.save_questions_to_database(questions, request.user_id)
return ExamGenerationResponse(
success=True,
questions=questions,
message="试题生成并保存成功",
total_count=len(questions)
)
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"试题生成失败: {str(e)}"
)

04

工具类的部分代码

classGraphState(TypedDict):
"""图状态定义"""
request: ExamGenerationRequest
questions: List[GeneratedQuestion]
current_question_index: int
knowledge_content: Dict[str, Any]
internet_results: List[str]
semantic_analysis: Dict[str, Any]
evaluation_results: List[Dict[str, Any]]
iteration_count: int
max_iterations: int
final_questions: List[GeneratedQuestion]
classLangGraphExamService:
"""基于LangGraph的试题生成服务"""
def__init__(self, db: Optional[AsyncSession] = None):
self.search_service = SearchService()
# 创建一个临时的exam_service实例,db参数会在实际使用时传入
self.exam_service = ExamGenerationService(db) if db elseNone
asyncdefgenerate_questions_with_workflow(
self,
request: ExamGenerationRequest,
db: Any  # 数据库会话
) -> List[GeneratedQuestion]:
"""
使用LangGraph工作流生成试题
Args:
request: 试题生成请求
db: 数据库会话
Returns:
生成的试题列表
"""
try:
# 初始化exam_service实例
self.exam_service = ExamGenerationService(db)
# 初始化LangGraph工作流
workflow = self._create_workflow()
app = workflow.compile(checkpointer=MemorySaver())
# 初始化状态
initial_state: GraphState = {
"request": request,
"questions": [],
"current_question_index": 0,
"knowledge_content": {},
"internet_results": [],
"semantic_analysis": {},
"evaluation_results": [],
"iteration_count": 0,
"max_iterations": 3,  # 最大迭代次数
"final_questions": []
}
# 执行工作流,添加配置参数
config = {"configurable": {"thread_id": "exam_generation_thread"}}
final_state = await app.ainvoke(initial_state, config=config)
return final_state["final_questions"]
except Exception as e:
logger.error(f"LangGraph试题生成失败: {str(e)}")
raise
def_create_workflow(self) -> StateGraph:
"""创建工作流"""
workflow = StateGraph(GraphState)
# 添加节点
workflow.add_node("retrieve_knowledge", self._retrieve_knowledge_node)
workflow.add_node("search_internet", self._search_internet_node)
workflow.add_node("semantic_analysis", self._semantic_analysis_node)
workflow.add_node("generate_question", self._generate_question_node)
workflow.add_node("evaluate_question", self._evaluate_question_node)
workflow.add_node("optimize_question", self._optimize_question_node)
workflow.add_node("finalize_questions", self._finalize_questions_node)
# 添加边
workflow.add_edge("retrieve_knowledge", "search_internet")
workflow.add_edge("search_internet", "semantic_analysis")
workflow.add_edge("semantic_analysis", "generate_question")
workflow.add_edge("generate_question", "evaluate_question")
workflow.add_conditional_edges(
"evaluate_question",
self._route_evaluation_result,
{
"optimize": "optimize_question",
"next": "generate_question",
"finalize": "finalize_questions"
}
)
workflow.add_edge("optimize_question", "evaluate_question")
workflow.add_edge("finalize_questions", END)
# 设置入口点
workflow.set_entry_point("retrieve_knowledge")
return workflow

由于代码量过大,不好粘贴,后期如果可能得话,我会放到github上面,供大家参考。

知识点解读

关于LangChain和LangGraph

      在搭建 AI Agent 时,很多团队会面临一个问题:到底选择 LangChain 还是 LangGraph?实际上,这取决于你的业务场景、Agent 的复杂度以及工作流需求。

LangChain:

特点:以 LLM 为核心,强调链式调用(Chain),擅长将多个工具或模型按顺序组合,实现多步推理。

适用场景:

任务流程较为线性或固定。

主要依赖提示词 + 工具调用。

快速构建原型或单一任务 Agent。

扩展性:

支持 React(Reasoning + Acting + Tool Use)模式,适合需要模型在推理过程中动态选择工具的场景。

LangGraph:

**特点:**以图为核心,强调状态管理和条件流控制(StateGraph),擅长处理复杂的多分支任务流程。

适用场景:

任务流程复杂,存在多个分支或条件依赖。

需要明确规划执行顺序(Plan-Execute)。

Agent 状态需要持续管理或可视化。

扩展性:

内置 Plan-Execute 模式,适合需要先制定计划再逐步执行的场景。

可与 React 模式结合,实现动态决策与条件流的统一管理。

选型建议

        如果你的 Agent 任务流程简单,且核心是快速响应与工具调用,LangChain + React 是首选。

如果你的 Agent 任务流程复杂,需要分支判断、状态管理或计划执行,LangGraph + Plan-Execute 更合适。

       对于复杂业务,也可以组合使用:用 LangGraph 管理整体状态与流程,用 LangChain 处理具体的链式任务调用。

未来我还会引入多Agent技术调用框架:AutoGentCamelXAgent等技术,敬请等待