基于LangGraph+FastAPI + 大模型的企业智能助手RAG知识引擎系统设计与实践21.5

举报
未闻花名 发表于 2026/07/26 20:55:21 2026/07/26
【摘要】 本项目基于LangGraph和FastAPI构建企业级智能助手系统,旨在解决传统人工客服响应滞后、知识碎片化等问题。系统具备四大核心功能:1)智能意图识别,自动区分知识问答、业务工具调用等场景;2)RAG检索增强问答,支持PDF/Markdown/TXT多格式知识库管理;3)业务工具集成,内置制度查询、工单查询等功能;4)多轮对话记忆。采用分层架构设计,包含前端展示层、API路由层、工作流引擎层等

一、项目规划

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不是简单的调用检索,在真正落地必须考虑幻觉规避、空结果兜底、多轮上下文、服务部署稳定性。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。