系列一我们用 21 篇文章系统学完了 LLM 基础、单 Agent、Context/RAG、多 Agent 到生产化——但那始终是"站在岸上学游泳"。每个概念都懂,真要做一个能在我公司里跑起来的东西,还是得自己下水。

所以系列二换一种写法:不讲了,直接做。 我会从零开始实现一个真实可用的"企业知识助手 Agent",并且把每一步的实现过程、决策理由、踩过的坑都写成文章——既是开发日记,也是教程。你看到的就是一个真实项目从空目录到上线的全过程。

如果你还没读过系列一,建议先看完,因为本项目会反复用到那里的概念:RAG(阶段三)、Function Calling(阶段二)、权限与安全(阶段五)。


我要做什么:需求清单

每个公司都有这类痛点:制度文档散落各处、年假余额得找 HR 问、流程说不清。我想做一个内部助手,同事用自然语言提问,它能:

能力说明技术对应
私有文件问答基于公司内部 PDF/Word 文档回答问题RAG
数据库查询比如"我还有几天年假",去数据库读数据参数化查询工具
权限控制张三不能问李四的年假身份注入 + 行级过滤
友好降级不知道或不能答时,给友好提示而非报错统一降级模板
流程图表现必要时用流程图说清步骤Mermaid 输出

注意最后一条:很多问答本质上是一套"流程"(比如请假步骤),文字描述很绕,用流程图一眼就懂。所以 Agent 在合适时要能输出 Mermaid 流程图。


整体架构

企业知识助手 Agent 架构

核心思路就一句话:用户身份从入口注入,之后所有数据访问都强制带上这个身份,模型只能决定"调不调工具",不能决定"查谁"。

流程是:

  1. 用户提问,入口层先鉴权,拿到 user_id(比如张三),把它注入到整条链路
  2. Agent 编排层(LLM + Function Calling)判断该调哪个工具
  3. 要么调 search_knowledge_base 走 RAG,要么调 get_leave_balance 走数据库
  4. 数据库查询强制行级过滤:只返回当前用户自己的数据
  5. 生成层组织答案,需要时输出 Mermaid
  6. 任何异常(检索为空 / 工具失败 / 模型判不可答)都走降级层给友好提示

技术选型与理由

选型为什么
语言Python 3.11+生态全,和主流 LLM 库对齐
WebFastAPI + 轻前端后端做登录和 Agent 逻辑,前端先快出 UI
LLM直连外网 API(OpenAI/Claude)配 key 即用
RAG 解析PyMuPDF + python-docx专治 PDF/Word
切分langchain RecursiveCharacterTextSplitter通用稳妥
EmbeddingOpenAI text-embedding-3-small云端 embedding,省本地算力
向量库ChromaDBMVP 最轻,后续可换 Qdrant
数据库SQLAlchemy + 参数化查询防注入,年假现成字段直接查
流程图Mermaid + 前端 mermaid.js文本即可渲染,可版本化
降级统一友好提示模板体验兜底

几个关键决策值得说清楚:

  • 数据库查询用"预定义函数"而不是 NL2SQL。年假是表里现成字段,直接 get_leave_balance(user_id) 查就行;NL2SQL 在内网 + 权限场景准确率和安全性都差,MVP 阶段不碰。
  • user_id 永远由服务端注入。工具暴露给模型的 schema 里 get_leave_balance() 根本没有 user 参数,模型想"查李四"也无从下手——这是后面要反复强调的红线。
  • Embedding 用云端。既然 LLM 都直连外网了,embedding 也用云端最省事。

文章阶段总览

系列二按"边做边写"组织,分 1 篇开篇 + 5 个阶段,每篇对应实现的一个真实里程碑:

阶段主题对应里程碑这篇记录什么
🗺 开篇为什么做 & 怎么搭总览需求、架构、选型、阶段计划(就是本文)
搭地基:最小闭环M0FastAPI 骨架 + LLM 接入 + 单轮问答;为什么先不碰 RAG/DB
让 Agent 读懂私有文件M1PDF/Word 解析→切分→Embedding→ChromaDB→检索→工具封装
查数据 + 守权限M2+M3SQLAlchemy 建模、参数化查询;JWT 登录、user_id 注入(权限红线)
更聪明更安全M4Mermaid 流程图触发;检索空/失败/不可答→友好降级
交给同事M5Web UI + 登录页 + 内网部署 + 项目复盘

阶段三把"查数据"和"守权限"合成一篇,因为权限是数据库查询的出厂约束,拆开反而割裂。


每篇文章怎么写

为了保证"边做边写"也有统一节奏,每篇都按这 7 个固定部分来:

  1. 本篇目标 / 当前进度 —— 做完后 Agent 能多干啥
  2. 设计决策 —— 我为什么这么选,包括被我否掉的方案
  3. 关键实现 —— 核心代码片段 + 讲解(不贴全文,讲清思路)
  4. 踩坑与调试 —— 真实遇到的问题、怎么解决的
  5. 验证效果 —— 跑起来的示例对话 / 截图
  6. 架构图更新 —— 当前阶段的 SVG
  7. 下一篇预告

这样你读到的不是事后美化的"标准答案",而是一个人真实把项目做出来的全过程。


一条红线

整个项目有一条绝对不能破的红线:权限

企业场景里,“张三查到李四的年假"不是 bug,是事故。所以权限不能靠"提醒模型别乱查"来实现,而是做成系统级的硬约束——user_id 从登录态来,数据库查询函数根本不接受外部传入的 user 参数。这条红线会贯穿阶段三,也会在测试环节专门验证。


下一篇预告

下一篇是阶段一:搭地基(M0)。我会从空目录开始,搭出 FastAPI 骨架、接通 LLM、跑通第一个单轮问答接口,并解释为什么第一步先不碰 RAG 和数据库——先把最不确定的"链路通不通"验证掉。

如果你也想从零做一个 Agent,欢迎跟着这个系列一起写。我们下篇见。