基于LangGraph+FastAPI + 大模型的企业智能助手RAG知识引擎系统设计与实践21.5
一、项目规划
1. 项目背景与业务定位
传统企业内部运营中,制度咨询、工单进度查询、产品FAQ解答、IT运维支持等场景高度依赖人工客服、行政及运维人员,普遍存在响应滞后、知识碎片化、重复劳动量大、答疑口径不统一、新人培训成本高等行业痛点。传统RAG问答系统仅支持简单线性检索,无法处理多意图识别、条件分支流转、业务工具调用、异常兜底等复杂企业场景,不具备生产落地能力。

本项目基于LangGraph有向图工作流、FastAPI高性能服务框架、开放大模型,搭建可直接上线的企业级智能助手,打通私有知识库检索与企业内部业务系统,实现自动化、精准化、规范化的智能服务,全面替代低价值人工咨询工作。核心适配四大企业场景,配套异常兜底机制,彻底解决大模型幻觉与服务失效问题。
|
核心场景 |
典型用户问题 |
项目落地效果 |
|---|---|---|
|
企业制度问答 |
年假有多少天、报销流程是什么、考勤扣款规则 |
秒级精准应答,支持文档来源溯源,回答严谨无编造 |
2. 项目需求分析
2.1 核心功能需求
- 智能意图识别:自动区分知识问答、业务工具调用、无关未知问题三大意图,驱动不同工作流分支
- RAG检索增强问答:基于企业私有知识库(员工手册、产品FAQ、IT指南、规章制度)实现精准语义检索,依托检索结果生成回答
- 严谨LLM生成能力:基于大模型,低温度参数约束,严禁编造信息,仅依托参考内容作答
- 业务工具集成:内置企业制度、工单查询、用户信息三大工具,支持对接企业内部OA、工单、HR系统接口
- 多轮对话记忆:支持上下文关联对话,自动裁剪历史记录,会话24小时自动过期
- 全量知识库管理:支持多格式文档上传、列表查看、删除、语义检索、索引一键重建
- 可视化前端面板:集成智能对话、知识库管理、工作流查看、服务自测四大功能模块
- 全链路服务自测:支持启动自动自检、手动全链路测试,快速排查服务异常
2.2 非功能需求
- 安全性:内置输入注入过滤、参数长度校验、文件名安全清洗,对话历史24小时自动过期,杜绝信息泄露与注入攻击
- 可观测性:全链路日志记录,检索过程输出候选分数、匹配文档,支持全流程问题溯源与参数调优
- 高可部署性:支持Docker Compose一键部署,适配Chroma轻量开发、Milvus生产级海量存储双向量库
- 低延迟高性能:本地Embedding模型推理,优化检索流水线,单轮对话响应时长稳定<5s
3. 整体架构选型
项目采用分层解耦架构,各组件选型兼顾开发效率、生产稳定性与可扩展性,完美适配企业私有化部署场景,具体选型如下:
|
架构层级 |
技术方案 |
|---|---|
|
Web服务框架 |
FastAPI,原生异步高性能,自动生成OpenAPI接口文档,支持高并发请求,适配后端服务场景 |
|
LangGraph |
支持有向图节点编排、条件分支、状态持久流转、异常分支兜底,解决传统LangChain线性流程短板 |
|
大模型服务 |
兼容OpenAI调用协议,低温度参数适配企业严谨问答场景,中文理解能力优异 |
|
paraphrase-multilingual-MiniLM-L12-v2 |
轻量化多语言模型,支持中英双语,384维向量,可本地私有化部署,无需联网 |
|
Chroma |
Chroma零依赖轻量化,适配本地开发调试; |
|
Redis |
持久化存储多轮对话,支持过期自动清理、会话裁剪,保障对话状态稳定 |
|
PyPDF + Unstructured + TextLoader |
全覆盖支持PDF、Markdown、TXT主流企业文档格式,解析准确率高 |
|
原生HTML/CSS/JS SPA |
零第三方依赖,部署极简,轻量化可视化面板,适配各类浏览器 |
4. 系统模块划分
系统采用分层模块化设计,从上至下依次为前端展示层、API路由层、工作流引擎层、核心能力层、数据存储层,各模块低耦合、可独立迭代扩展:
- 前端SPA调试面板:集成智能对话、知识库管理、工作流监控、服务自测四大可视化功能,直观展示检索来源、对话意图、服务状态
- API路由层:统一对外提供对话、知识库、工作流、服务自测接口,支撑前端与第三方系统对接
- LangGraph工作流引擎层:核心业务调度中心,实现意图识别、分支流转、节点执行、异常兜底全流程管控
- 核心能力层:包含RAG检索引擎、业务工具集群、Redis对话记忆、安全校验工具,支撑核心业务能力
- 数据存储层:向量数据库存储文档向量、Redis缓存会话数据、本地目录存储原始知识库文档
二、项目构建详情
1. 完整技术栈清单
|
技术类别 |
组件名称 |
适配版本 |
|---|---|---|
|
开发语言 |
Python |
3.11+ |
|
AI框架 |
LangChain、LangGraph |
≥0.2.0 |
|
Web服务 |
FastAPI、Uvicorn |
≥0.115.0 |
|
大模型服务 |
本地模型部署/大模型API服务 |
最新稳定版 |
|
嵌入模型 |
MiniLM-L12-v2 |
开源稳定版 |
|
向量数据库 |
ChromaDB |
≥0.5.0 |
|
缓存服务 |
Redis |
≥5.0.0 |
|
容器部署 |
Docker、Docker Compose |
最新稳定版 |
2. 标准化目录结构
项目遵循企业后端开发规范,模块化拆分、职责清晰,支持团队协作与迭代升级,完整目录如下:
langgraph-enterprise-bot/ ├── app/ │ ├── main.py # FastAPI入口:生命周期、路由注册、启动自检 │ ├── config.py # 全局配置中心:模型、向量库、缓存、检索参数 │ ├── api/ # 接口路由层 │ │ ├── chat.py # 智能对话核心接口 │ │ ├── knowledge.py # 知识库管理接口 │ │ ├── workflow.py # 工作流状态管理接口 │ │ └── test.py # 服务自测接口 │ ├── core/ # 核心能力引擎 │ │ ├── rag_engine.py # RAG检索核心流水线 │ │ └── chat_memory.py # Redis多轮对话记忆管理 │ ├── db/ # 数据层封装 │ │ ├── vector_db.py # 向量库统一操作封装 │ │ └── redis_db.py # Redis异步连接池 │ ├── graph/ # LangGraph工作流核心 │ │ ├── state.py # 全局状态定义 │ │ ├── nodes.py # 业务流程节点 │ │ ├── edges.py # 条件分支路由 │ │ └── workflow_graph.py # 工作流组装编译 │ ├── tools/ # 企业业务工具集群 │ │ ├── rule_tool.py # 公司制度查询工具 │ │ ├── ticket_tool.py # 工单进度查询工具 │ │ └── user_tool.py # 员工信息查询工具 │ ├── utils/ # 通用工具函数 │ │ ├── logger.py # 全链路日志配置 │ │ ├── doc_loader.py # 多格式文档解析 │ │ └── validator.py # 安全参数校验 │ └── static/ │ └── index.html # 前端SPA可视化面板 ├── tests/ │ └── test_service.py # 全链路自动化测试脚本 ├── data/ # 企业知识库原始文档目录 │ ├── 员工手册.txt │ ├── 产品FAQ.txt │ └── IT支持指南.txt ├── docker-compose.yml # 全服务容器编排配置 ├── Dockerfile # 项目镜像构建文件 ├── requirements.txt # 依赖版本锁定清单 └── README.md # 项目部署使用文档
3. 核心模块详细解析
3.1 全局配置中心(config.py)
统一管理全系统可调参数,支持环境变量动态覆盖,区分开发/生产环境,无需修改核心代码即可调整业务逻辑,核心配置如下:
|
配置项 |
默认值 |
功能说明 |
|---|---|---|
|
LLM_MODEL_NAME |
hy3-preview |
指定腾讯混元大模型版本 |
|
LLM_TEMPERATURE |
0.1 |
低温度约束,杜绝模型幻觉,保障回答严谨 |
|
EMBEDDING_MODEL_PATH |
本地MiniLM模型路径 |
私有化嵌入模型,无需联网调用 |
|
SIMILARITY_TOP_K |
5 |
单次检索返回Top5相关文档片段 |
|
SIMILARITY_THRESHOLD |
1.8 |
向量L2距离过滤阈值,筛选高匹配内容 |
|
MAX_CHAT_HISTORY |
10 |
单会话最多保留10轮对话,避免上下文溢出 |
import os
from dotenv import load_dotenv
load_dotenv()
# ============================================================
# 腾讯混元大模型配置(TokenHub平台)
# ============================================================
LLM_API_KEY = os.getenv(
"TENCENT_API_KEY",
"sk-ymLiA.....",
)
LLM_BASE_URL = os.getenv(
"LLM_BASE_URL",
"https://tokenhub.tencentmaas.com/v1",
)
LLM_MODEL_NAME = os.getenv("LLM_MODEL_NAME", "hy3-preview")
LLM_TEMPERATURE = 0.1 # 低温度,保证业务回答严谨
# ============================================================
# 向量数据库配置(使用 Chroma 本地向量库)
# ============================================================
VECTOR_DB_TYPE = "chroma"
COLLECTION_NAME = "enterprise_knowledge"
# ============================================================
# 本地 Embedding 模型配置
# ============================================================
EMBEDDING_MODEL_PATH = os.getenv(
"EMBEDDING_MODEL_PATH",
r"D:\modelscope\hub\sentence-transformers\paraphrase-multilingual-MiniLM-L12-v2",
)
# ============================================================
# Redis 配置
# ============================================================
REDIS_HOST = os.getenv("REDIS_HOST", "localhost")
REDIS_PORT = int(os.getenv("REDIS_PORT", "6379"))
REDIS_DB = int(os.getenv("REDIS_DB", "0"))
# ============================================================
# 对话配置
# ============================================================
MAX_CHAT_HISTORY = 10
SIMILARITY_TOP_K = 5 # 检索 top-5 相似文档
SIMILARITY_THRESHOLD = 1.8 # L2 距离阈值,超过此值视为不相关(值越小越严格;归一化向量范围 0~2)
3.2 安全校验模块(validator.py)
为系统提供全方位安全防护,规避注入攻击与异常参数导致的服务故障,核心能力:
- 注入过滤:自动清除<script>、{{ }}、<% %>等恶意注入标签与脚本
- 参数长度限制:用户提问≤2000字符,单篇文档内容≤50000字符,防止超大参数压垮服务
- 文件安全清洗:自动替换文件名非法字符,禁止隐藏文件上传,保障知识库安全
"""请求校验器 —— 输入安全校验 & 参数合法性检查。"""
import re
from typing import Optional
from pydantic import BaseModel, Field, field_validator
# ------------------------------------------------------------
# 校验规则常量
# ------------------------------------------------------------
MAX_QUERY_LENGTH = 2000
FORBIDDEN_PATTERNS = [
re.compile(r"<script.*?>", re.IGNORECASE),
re.compile(r"\{\{.*?\}\}"),
re.compile(r"<%[^>]*%>"),
]
class ChatRequest(BaseModel):
"""对话请求模型(含校验)"""
query: str = Field(..., min_length=1, max_length=MAX_QUERY_LENGTH, description="用户提问")
chat_history: list = Field(default_factory=list, description="多轮对话历史")
session_id: Optional[str] = Field(default=None, max_length=64, description="会话标识")
@field_validator("query")
@classmethod
def sanitize_query(cls, v: str) -> str:
"""去除首尾空白,过滤潜在注入字符。"""
v = v.strip()
if not v:
raise ValueError("query 不能为空")
for pattern in FORBIDDEN_PATTERNS:
v = pattern.sub("", v)
return v
@field_validator("session_id")
@classmethod
def validate_session_id(cls, v: Optional[str]) -> Optional[str]:
if v and not re.fullmatch(r"[a-zA-Z0-9_-]+", v):
raise ValueError("session_id 只能包含字母、数字、下划线和连字符")
return v
class KnowledgeUploadRequest(BaseModel):
"""知识文档上传请求"""
file_name: str = Field(..., min_length=1, max_length=255)
content: str = Field(..., min_length=1)
@field_validator("file_name")
@classmethod
def sanitize_filename(cls, v: str) -> str:
# 只保留安全字符
v = re.sub(r"[^\w.\-]", "_", v)
if v.startswith("."):
v = "_" + v
return v
@field_validator("content")
@classmethod
def validate_content(cls, v: str) -> str:
if len(v) > 50_000:
raise ValueError("单篇文档内容不能超过 50000 字符")
return v
3.3 文档加载解析模块(doc_loader.py)
自动扫描本地知识库目录,根据文档后缀自动匹配对应加载器,全覆盖企业常用文档格式,解析后统一标准化输出,为向量化提供干净数据源。支持PDF、Markdown、TXT三种主流格式,兼容UTF-8编码文档,自动过滤空白内容与无效换行。
"""企业文档加载器 —— 支持 PDF / Markdown / TXT 等多种格式。"""
import os
from pathlib import Path
from typing import List
from langchain_community.document_loaders import PyPDFLoader, TextLoader, UnstructuredMarkdownLoader
from langchain_core.documents import Document
from app.utils.logger import logger
DATA_DIR = Path(__file__).resolve().parent.parent.parent / "data"
def load_all_documents(data_dir: Path | None = None) -> List[Document]:
"""
递归扫描 data/ 目录,加载所有支持格式的文档。
支持格式:.pdf .md .txt
"""
if data_dir is None:
data_dir = DATA_DIR
all_docs: List[Document] = []
if not data_dir.exists():
logger.warning("data/ 目录不存在,无文档可加载:%s", data_dir)
return all_docs
for file_path in data_dir.rglob("*"):
if file_path.is_dir() or file_path.name.startswith("."):
continue
suffix = file_path.suffix.lower()
try:
if suffix == ".pdf":
loader = PyPDFLoader(str(file_path))
elif suffix == ".md":
loader = UnstructuredMarkdownLoader(str(file_path))
elif suffix == ".txt":
loader = TextLoader(str(file_path), encoding="utf-8")
else:
continue
docs = loader.load()
for doc in docs:
doc.metadata.setdefault("source", str(file_path))
all_docs.extend(docs)
logger.info("已加载文档:%s(%d 页/段)", file_path.name, len(docs))
except Exception:
logger.exception("文档加载失败:%s", file_path)
logger.info("文档加载完成,共 %d 条记录", len(all_docs))
return all_docs
3.4 多轮对话记忆模块(chat_memory.py)
基于Redis List结构实现会话级多轮对话管理,以唯一session_id作为会话标识,核心能力:
- 持久化存储:对话消息序列化后存入Redis,支持跨请求上下文关联
- 自动裁剪:保留最近10轮对话,自动清理过期历史,避免上下文冗余
- 过期清理:所有会话24小时自动失效,保障数据安全,减少缓存占用
"""对话记忆管理 —— 基于 Redis 的多轮对话历史存取。"""
import json
from typing import Dict, List, Optional
from app.config import MAX_CHAT_HISTORY
from app.db.redis_db import get_redis
from app.utils.logger import logger
KEY_PREFIX = "chat:history:"
async def save_message(session_id: str, role: str, content: str) -> None:
"""保存单条消息到会话历史。"""
redis = await get_redis()
key = f"{KEY_PREFIX}{session_id}"
msg = json.dumps({"role": role, "content": content}, ensure_ascii=False)
await redis.rpush(key, msg)
await redis.ltrim(key, -MAX_CHAT_HISTORY * 2, -1) # 保留最近N轮(每轮一问一答)
await redis.expire(key, 3600 * 24) # 24h 过期
async def get_history(session_id: str) -> List[Dict[str, str]]:
"""获取会话完整对话历史。"""
redis = await get_redis()
key = f"{KEY_PREFIX}{session_id}"
raw = await redis.lrange(key, 0, -1)
return [json.loads(m) for m in raw]
async def clear_history(session_id: str) -> None:
"""清除指定会话历史。"""
redis = await get_redis()
await redis.delete(f"{KEY_PREFIX}{session_id}")
logger.info("已清除会话历史:%s", session_id)
3.5 企业业务工具集群(tools/)
内置三大落地业务工具,完成业务闭环:
- 企业制度查询工具:覆盖请假、报销、考勤、加班、信息安全等通用企业制度,内置标准化规则库
"""企业规章制度查询工具 —— 检索公司内部条例与管理办法。"""
from langchain_core.tools import tool
from app.utils.logger import logger
# 企业规章制度库
_ENTERPRISE_RULES = {
"请假": "员工请假需提前 1 个工作日在 OA 系统提交申请,3 天以内由直属领导审批,3 天以上需部门负责人加签。",
"报销": "差旅报销需在行程结束后 7 个工作日内提交,附带正规发票和审批单,超标部分由个人承担。",
"考勤": "弹性工作制:核心工作时间 10:00-17:00,月累计迟到超过 3 次将记入当月绩效。",
"加班": "加班需提前报备,工作日加班按 1.5 倍时薪计算,休息日 2 倍,法定节假日 3 倍。",
"信息安全": "禁止使用未经审批的外部存储设备;所有内部文档不得通过非授权渠道外传。",
}
@tool
def query_enterprise_rule(query: str) -> str:
"""
企业规章制度与管理办法查询工具。
Args:
query: 制度关键词(如:请假、报销、考勤、加班、信息安全)
Returns:
匹配的制度条款原文或提示信息。
"""
for keyword, rule_text in _ENTERPRISE_RULES.items():
if keyword in query:
logger.info("命中企业制度:%s", keyword)
return f"【{keyword}】{rule_text}"
logger.info("未命中企业制度,query=%s", query)
return "未找到相关制度条款,建议查阅《公司员工手册》或咨询 HR 部门。"
- 工单查询工具:支持对接企业工单API,实时查询工单状态、进度、处理人,自动处理接口异常
from langchain_core.tools import tool
import requests
from app.utils.logger import logger
@tool
def query_enterprise_ticket(ticket_id: str) -> str:
"""
企业工单状态查询工具。
Args:
ticket_id: 工单编号
Returns:
工单详细状态、处理进度、处理人。
"""
try:
# 对接企业内部工单系统 API(真实业务接口)
res = requests.get(
f"http://enterprise-api.local/ticket/{ticket_id}", timeout=5
)
if res.status_code == 200:
data = res.json()
return (
f"工单{ticket_id}状态:{data['status']},"
f"处理人:{data['operator']},"
f"进度:{data['progress']}"
)
logger.warning("工单查询失败:%s, status=%d", ticket_id, res.status_code)
return f"工单{ticket_id}查询失败,暂无数据"
except Exception as e:
logger.exception("工单查询异常:%s", ticket_id)
return f"工单查询异常:{str(e)},请人工核查"
- 用户信息工具:查询员工部门、职位、联系方式,支撑内部人员信息咨询场景
"""用户信息查询工具 —— 对接企业 HR / 通讯录系统。"""
from langchain_core.tools import tool
from app.utils.logger import logger
# 模拟的用户信息库(生产环境对接企业 LDAP / HR 系统)
_MOCK_USERS = {
"zhangsan": {"name": "张三", "department": "技术部", "position": "高级工程师", "email": "zhangsan@company.com"},
"lisi": {"name": "李四", "department": "产品部", "position": "产品经理", "email": "lisi@company.com"},
"wangwu": {"name": "王五", "department": "运营部", "position": "运营总监", "email": "wangwu@company.com"},
}
@tool
def query_user_info(user_identifier: str) -> str:
"""
企业用户信息查询工具。
Args:
user_identifier: 员工工号 / 用户名 / 邮箱前缀
Returns:
用户部门、职位、联系方式等信息。
"""
user = _MOCK_USERS.get(user_identifier.lower())
if user:
logger.info("用户查询成功:%s", user_identifier)
return (
f"姓名:{user['name']} | "
f"部门:{user['department']} | "
f"职位:{user['position']} | "
f"邮箱:{user['email']}"
)
logger.info("未找到用户:%s", user_identifier)
return f"未查询到 {user_identifier} 的员工信息,请核对账号后重试。"
4. LangGraph工作流引擎核心
工作流引擎是本项目核心差异化能力,区别于传统线性RAG,通过状态定义、独立节点、条件分支、异常兜底实现复杂企业业务逻辑,支持灵活迭代扩展。
4.1 全局状态定义(state.py)
基于TypedDict定义标准化工作流状态,统一存储全流程核心数据,实现节点间状态互通,包含8大核心字段:用户提问、对话历史、意图类型、检索文档、工具结果、最终答案、异常信息、人工兜底标记。全程状态可追溯、可监控、可回溯。
from typing import Any, Dict, List, Optional, TypedDict
class GraphState(TypedDict, total=False):
"""企业工作流全局状态 —— TypedDict 与 LangGraph StateGraph 原生兼容。"""
user_query: str
chat_history: List[Dict[str, str]]
intent_type: Optional[str]
retrieve_docs: List[Any]
tool_result: Optional[str]
answer: Optional[str]
error_msg: Optional[str]
need_human: bool
def create_initial_state(
user_query: str = "",
chat_history: Optional[List[Dict[str, str]]] = None,
) -> GraphState:
"""创建初始状态字典(节点入口可用)。"""
return GraphState(
user_query=user_query,
chat_history=chat_history or [],
intent_type=None,
retrieve_docs=[],
tool_result=None,
answer=None,
error_msg=None,
need_human=False,
)
4.2 五大核心业务节点(nodes.py)
所有节点独立解耦、可单独迭代,各司其职完成全流程处理:
- 意图识别节点:依托腾讯混元大模型,精准分类knowledge知识问答、tool业务工具、unknown未知问题三大意图
- 知识检索节点:调用RAG引擎,基于用户提问检索私有知识库,输出高匹配文档片段
- 工具调用节点:根据用户问题自动匹配对应业务工具,提取参数并执行业务查询
- 答案生成节点:融合检索结果、工具数据、对话历史,生成严谨、规范、无编造的最终回答
- 人工兜底节点:捕获接口异常、无效参数、未知问题等场景,自动阻断模型幻觉,提示人工介入
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from app.config import LLM_API_KEY, LLM_BASE_URL, LLM_MODEL_NAME, LLM_TEMPERATURE
from app.core.rag_engine import retrieve_knowledge_docs
from app.graph.state import GraphState
from app.tools.ticket_tool import query_enterprise_ticket
# ---------- 初始化大模型 ----------
llm = ChatOpenAI(
api_key=LLM_API_KEY,
base_url=LLM_BASE_URL,
model=LLM_MODEL_NAME,
temperature=LLM_TEMPERATURE,
)
# =============================================================
# 1. 意图识别节点
# =============================================================
def intent_recognize_node(state: GraphState) -> GraphState:
"""识别用户提问意图:知识问答 / 业务工具 / 未知问题。"""
prompt = ChatPromptTemplate.from_template("""\
你是企业智能助手,请识别用户提问意图,仅返回:knowledge / tool / unknown
规则:
1. 询问公司制度、手册、流程规范、产品知识 → knowledge
2. 查询工单、数据、业务办理 → tool
3. 无关问题、模糊问题 → unknown
用户提问:{user_query}
""")
chain = prompt | llm
intent = chain.invoke({"user_query": state["user_query"]}).content.strip()
new_state = dict(state)
new_state["intent_type"] = intent
return new_state
# =============================================================
# 2. 知识检索节点
# =============================================================
def knowledge_retrieve_node(state: GraphState) -> GraphState:
"""RAG 知识库检索。"""
docs = retrieve_knowledge_docs(state["user_query"])
new_state = dict(state)
new_state["retrieve_docs"] = docs
return new_state
# =============================================================
# 3. 工具调用节点
# =============================================================
def tool_invoke_node(state: GraphState) -> GraphState:
"""根据提问调用对应业务工具。"""
import re
new_state = dict(state)
try:
if "工单" in state["user_query"]:
ticket_ids = re.findall(r"T\d+", state["user_query"])
if ticket_ids:
res = query_enterprise_ticket.invoke(ticket_ids[0])
new_state["tool_result"] = res
return new_state
new_state["tool_result"] = "未识别到有效业务参数,无法查询"
except Exception as e:
new_state["error_msg"] = str(e)
new_state["need_human"] = True
return new_state
# =============================================================
# 4. 答案生成节点
# =============================================================
def generate_answer_node(state: GraphState) -> GraphState:
"""结合检索结果 / 工具结果生成最终答案。"""
context = ""
if state.get("retrieve_docs"):
context = "\n".join([doc.page_content for doc in state["retrieve_docs"]])
if state.get("tool_result"):
context += f"\n业务查询结果:{state['tool_result']}"
prompt = ChatPromptTemplate.from_template("""\
你是专业的企业内部智能助手,基于以下参考内容回答用户问题,回答严谨、简洁、准确,禁止编造信息。
参考内容:{context}
用户问题:{user_query}
对话历史:{chat_history}
""")
chain = prompt | llm
answer = chain.invoke({
"context": context,
"user_query": state["user_query"],
"chat_history": state.get("chat_history", []),
}).content
new_state = dict(state)
new_state["answer"] = answer
return new_state
# =============================================================
# 5. 人工兜底节点
# =============================================================
def human_fallback_node(state: GraphState) -> GraphState:
"""异常场景人工介入兜底。"""
new_state = dict(state)
new_state["answer"] = (
f"当前问题暂时无法自动处理,已为您转接人工客服,"
f"异常信息:{state.get('error_msg', '未知异常')}"
)
return new_state
4.3 条件分支路由(edges.py)
实现智能流程流转,无需硬编码逻辑,动态适配不同用户场景:
- 意图分支路由:知识问答走检索流程、业务查询走工具调用、未知问题直接生成兜底回答
- 异常分支路由:检测到异常信息或人工兜底标记时,自动跳转人工兜底节点,正常流程直接结束
from app.graph.state import GraphState
def intent_route_edge(state: GraphState) -> str:
"""意图分支路由。"""
intent = state.get("intent_type", "")
if intent == "knowledge":
return "knowledge_retrieve"
elif intent == "tool":
return "tool_invoke"
return "generate_answer"
def error_route_edge(state: GraphState) -> str:
"""异常分支路由。"""
if state.get("need_human") or state.get("error_msg"):
return "human_fallback"
return "end"
4.4 工作流拓扑结构(workflow_graph.py)
入口意图识别 → 条件分支分流(知识检索/工具调用/直接生成) → 统一汇聚答案生成 → 异常检测分支 → 人工兜底/流程结束,形成完整闭环,支持复杂场景迭代扩展。

from langgraph.graph import StateGraph, END
from app.graph.edges import error_route_edge, intent_route_edge
from app.graph.nodes import (
generate_answer_node,
human_fallback_node,
intent_recognize_node,
knowledge_retrieve_node,
tool_invoke_node,
)
from app.graph.state import GraphState
def build_workflow_graph():
"""构建并编译企业级 LangGraph 工作流。"""
# 初始化状态图
graph = StateGraph(GraphState)
# 注册所有节点
graph.add_node("intent_recognize", intent_recognize_node)
graph.add_node("knowledge_retrieve", knowledge_retrieve_node)
graph.add_node("tool_invoke", tool_invoke_node)
graph.add_node("generate_answer", generate_answer_node)
graph.add_node("human_fallback", human_fallback_node)
# 设置入口节点
graph.set_entry_point("intent_recognize")
# 配置意图分支流转
graph.add_conditional_edges(
"intent_recognize",
intent_route_edge,
{
"knowledge_retrieve": "knowledge_retrieve",
"tool_invoke": "tool_invoke",
"generate_answer": "generate_answer",
},
)
# 固定节点流转:检索/工具 → 答案生成
graph.add_edge("knowledge_retrieve", "generate_answer")
graph.add_edge("tool_invoke", "generate_answer")
# 异常兜底分支
graph.add_conditional_edges(
"generate_answer",
error_route_edge,
{
"human_fallback": "human_fallback",
"end": END,
},
)
graph.add_edge("human_fallback", END)
# 编译图
return graph.compile()
# 全局单例工作流
enterprise_workflow = build_workflow_graph()
5. RAG检索引擎流水线
项目优化传统RAG短板,搭建高精度、高可用、可追溯的企业级检索流水线,彻底解决检索不准、信息缺失、幻觉频发问题。
5.1 完整执行流程
用户提问 → 文本智能切片 → 本地Embedding向量化 → 向量库存储检索 → 阈值过滤+文档去重 → LLM严谨生成回答

5.2 核心优化策略
- 精细化切片策略:分片400字符+80字符重叠,兼顾片段粒度与内容完整性,避免关键信息割裂
- 多级分隔符适配:按段落、换行、句号、逗号逐级拆分,适配各类企业文档排版
- 软回退兜底机制:阈值过滤无结果时,自动回退原始Top-K检索结果,保证永不空应答
- 文档去重优化:同一源文档仅保留最相关片段,避免重复信息干扰模型生成
- 全流程可观测:日志打印每一条检索候选的匹配分数,支持人工调优阈值参数

6. 前端可视化界面
基于原生HTML/CSS/JS开发单页面应用(SPA),零依赖、部署简单、交互直观,集成四大核心功能面板:
- 智能对话面板:支持快捷提问、多轮对话、意图标签展示、RAG检索来源折叠查看,区分模型生成内容与参考数据源

- 知识库管理面板:支持文档上传、删除、列表查看、语义检索、索引一键重建

- 工作流引擎面板:可视化查看工作流节点状态、手动触发流程执行、监控流程流转情况
- 服务自测面板:支持7项全量自测、3项快速检测,自动生成服务健康报告
界面采用企业风深蓝配色,区分用户消息、助手回复、检索来源区域,视觉层级清晰,适配日常运维与使用。
三、项目落地部署与使用
1. 双模式环境部署
1.1 本地开发部署模式
适配本地调试、功能迭代,轻量高效,步骤极简:
# 1. 安装项目依赖
pip install -r requirements.txt
# 2. 配置API密钥(环境变量)
export API_KEY="你的API密钥"
# 3. 启动本地Redis缓存
docker run -d --name redis -p 6379:6379 redis:7-alpine
# 4. 启动后端服务
python -m uvicorn app.main:app --host 0.0.0.0 --port 8001
# 5. 访问前端页面
# 浏览器打开:http://localhost:8001
1.2 Docker生产部署模式
一键编排全量服务,包含应用、Redis、Chroma向量库、元数据服务、对象存储,适配企业生产环境:
# 一键启动所有服务
docker compose up -d
# 查看服务运行日志
docker compose logs -f app
# 停止所有服务
docker compose down
Docker编排服务包含:8001端口主应用服务、6379端口Redis缓存、2379端口etcd元数据服务、9000端口Minio对象存储,全覆盖生产所需组件。
2. 全维度服务测试
2.1 启动自动自检
服务启动后自动执行7项核心自检,覆盖服务健康、目录资源、模型加载、知识库、检索能力、工作流、对话能力,全部通过后方可正常使用,异常项精准日志提示。

2.2 手动全链路测试
支持脚本批量测试,包含4阶段9项测试,可自定义测试地址、跳过耗时项目、开启详细日志:
# 全量测试
python tests/test_service.py
# 指定服务地址测试
python tests/test_service.py --url http://localhost:8001
# 跳过耗时测试项
python tests/test_service.py --skip-heavy
# 输出详细测试日志
python tests/test_service.py -v
2.3 前端可视化自测
通过前端“服务自测”面板,点击按钮即可完成快速检测与全量测试,自动生成可视化测试报告,无需命令行操作。

3. 核心功能使用指南
3.1 智能对话使用流程
用户输入问题 → 系统自动识别意图 → 匹配对应工作流(检索/工具/兜底) → 执行处理 → 生成带来源溯源的回答 → 前端展示检索参考片段与意图标签。

所有制度类、业务类、IT咨询类问题均可秒级响应。

3.2 知识库管理使用流程
支持手动上传文档、查看知识库列表、删除冗余文档、手动语义检索、修改文档后一键重建索引,全程可视化操作,无需修改代码即可更新企业知识内容。
4. 完整API接口清单
4.1 对话服务接口
- POST /chat/ask:核心智能对话接口,支持多轮问答
- GET /health:服务健康状态检测接口
4.2 知识库管理接口
- GET /knowledge/list:获取所有知识库文档列表
- POST /knowledge/upload:上传新的知识库文档
- DELETE /knowledge/{file_name}:删除指定文档
- POST /knowledge/search:纯语义检索测试
- POST /knowledge/rebuild:重建向量索引
4.3 工作流管理接口
- GET /workflow/status:查询工作流引擎状态
- POST /workflow/execute:手动触发工作流执行
4.4 服务自测接口
- GET /test/all:执行7项全量服务测试
- GET /test/quick:执行3项快速健康检测
四、项目总结
项目从零搭建生产级企业智能助手系统,实现全业务闭环落地:
- 完成意图识别、RAG检索、工具调用、多轮对话、人工兜底全链路智能问答能力
- 支持多格式企业知识库管理,实现文档解析、向量化、检索、索引更新全自动化
- 内置企业真实业务工具,可对接内部OA、工单、HR系统,落地业务自动化
- 实现会话安全管控、输入安全校验、全链路日志监控,满足企业安全规范
- 提供可视化前端面板、自动化测试体系、Docker一键部署方案,上线成本极低
- 区分开发/生产双向量库,兼顾开发效率与生产高可用,适配企业私有化部署
项目核心技术应用:
- 有向图智能编排:基于LangGraph实现条件分支、状态流转、异常兜底,解决传统RAG线性流程僵硬问题
- RAG软回退机制:阈值过滤无结果自动回退Top-K检索,彻底杜绝空应答问题
- 问答全溯源:前端独立展示检索来源原文,模型生成内容与参考内容明确分隔,可追溯、可核验
- 高安全高可用:多层安全校验、会话过期清理、异常自动兜底、全链路日志可观测
总的来说,企业级 AI 项目拼的不是模型大小,而是工程细节。比如RAG软回退、文档去重、阈值调优、日志可观测、安全校验这些看似不起眼的设计,才是系统能商用的关键。RAG不是简单的调用检索,在真正落地必须考虑幻觉规避、空结果兜底、多轮上下文、服务部署稳定性。
- 点赞
- 收藏
- 关注作者

评论(0)