首页
看点啥
插画图片
首页 看点啥 从零搭建RAG知识库问答系统:零基础自学agent日记

从零搭建RAG知识库问答系统:零基础自学agent日记

2026-07-21 0

从零搭建 RAG 知识库问答系统:我的 LangChain + Agent 学习笔记

前言

最近花了两周时间,系统学习了 LangChain 生态,从 Prompt 模板到 RAG 检索,再到 Agent 工具调用。通过 smart-office-assistant 这个项目,把所有知识点串联了起来。

从零搭建RAG知识库问答系统(零基础自学agent日记)

这篇文章不讲"怎么实现",而是分享"我学到了什么"——那些踩过的坑、理清的概念、形成的知识体系。

一、LangChain 核心概念梳理

刚开始学 LangChain 时,概念太多容易晕。我梳理了一个清晰的认知框架:

1.1 LangChain 的三大支柱

┌─────────────────────────────────────────────────────────┐│LangChain 生态│├─────────────────┬─────────────────┬─────────────────────┤│ LangChain │ LangGraph │ LangServe ││ (基础组件)│ (Agent编排) │ (部署服务)│├─────────────────┼─────────────────┼─────────────────────┤│ - Prompt│ - StateGraph│ - REST API││ - LLM │ - Nodes/Edges │ - Web UI││ - Chains│ - Conditional │ - Streaming ││ - Tools │ - Memory│ ││ - Retrievers│ │ │└─────────────────┴─────────────────┴─────────────────────┘

我的理解:

1.2 关键概念关系图

Prompt Template (提示模板) ↓LLM (大语言模型) ↓ Output Parser (输出解析) ↓Chain (处理链) ↓Agent (智能袋里) ← 工具调用 ↓ Memory (记忆系统)

学习心得:

概念一句话理解类比
Prompt Template给 AI 的填空题模板考试题模板
LLM会答题的大脑考生
Chain固定流程的流水线流水线工人
Agent能自己决定下一步的决策者项目经理
ToolsAI 可以调用的外部能力员工
Memory让 AI 记住上下文笔记本

二、RAG:让 AI 基于你的文档回答

2.1 RAG 解决了什么问题?

纯 LLM 的痛点:

RAG 的思路:

用户提问 → 先检索相关文档 → 把文档喂给 LLM → LLM 基于文档生成答案

2.2 RAG 的核心流程

我总结了一个 RAG 五步法:

┌─────────────────────────────────────────────────────────┐│RAG 五步法│├─────────────────────────────────────────────────────────┤│1. 文档加载 →把各种格式的文档读进来 ││2. 文档切分 →把长文档切成小块(chunks) ││3. 向量化 →用 Embedding 模型把文本变成向量││4. 存储检索 →存入向量数据库,支持相似度搜索 ││5. 生成答案 →检索相关文档,交给 LLM 生成回答│└─────────────────────────────────────────────────────────┘

2.3 踩过的坑和经验

坑1:文档切分太粗或太细

问题:chunk_size 设太大,检索不精确;设太小,丢失上下文。

我的经验:

# 推荐配置(中文文档)splitter = RecursiveCharacterTextSplitter(chunk_size=300,# 中文300字左右chunk_overlap=50,# 重叠50字保持连贯separators=["nn", "n", "。", ",", " "],# 优先按段落切)

关键点:

坑2:Embedding 模型选错

问题:用英文 Embedding 模型处理中文,效果很差。

我的选择:

# 中文推荐:bge-small-zh-v1.5# 体积小(~100MB),中文效果好embedding = HuggingFaceEmbeddings(model_name="AI-ModelScope/bge-small-zh-v1.5",model_kwargs={"device": "cpu"},encode_kwargs={"normalize_embeddings": True},)

模型对比:

模型语言体积效果
text-embedding-ada-002英文为主API调用英文好
bge-small-zh-v1.5中文~100MB中文好
bge-large-zh-v1.5中文~1.3GB中文最好
坑3:每次启动都重新构建向量库

问题:文档没变,但每次启动都重新构建,浪费时间。

解决方案:用哈希值检测文档变化

def get_docs_hash(docs_dir):"""计算文档目录的哈希值"""hash_obj = hashlib.md5()for root, dirs, files in os.walk(docs_dir):for filename in sorted(files):filepath = os.path.join(root, filename)stat = os.stat(filepath)# 文件名 + 修改时间 + 大小 = 唯一标识hash_obj.update(f"{filename}{stat.st_mtime}{stat.st_size}".encode())return hash_obj.hexdigest()

经验:哈希值只在文档变化时才改变,实现了智能缓存。

2.4 RAG 优化方向

优化点方法效果
检索优化使用 MMR(最大边际相关性)避免返回重复内容
重排序对检索结果二次排序提升相关性
混合检索向量检索 + 关键词检索兼顾语义和精确匹配
多路召回多种方式检索,合并结果提升召回率

三、Agent:让 AI 自己决定用什么工具

3.1 Agent 是什么?

我的理解:Agent = LLM + Tools + 决策能力

Chain 的工作方式:用户 → Step1 → Step2 → Step3 → 回答(固定流程)Agent 的工作方式:用户 → LLM 判断 → 调用工具A → LLM 判断 → 调用工具B → 回答(动态决策)

3.2 工具调用的核心机制

通过 @tool 装饰器定义工具:

from langchain_core.tools import tool@tooldef calculator(expression: str) -> str:"""计算数学表达式。这是工具的描述,AI会根据这个判断什么时候用。Args:expression: 数学表达式,例如 "2 + 3 * 4""""import numexprresult = numexpr.evaluate(expression)return f"{expression} = {result.item()}"

关键点:

3.3 ReAct 模式

Agent 的核心是 ReAct(Reasoning + Acting)模式:

┌─────────────────────────────────────────────────────────┐│ReAct 循环│├─────────────────────────────────────────────────────────┤│ ││ Thought (思考)→Action (行动)→Observation (观察) ││↑│ ││└────────────────────────────────────┘ ││ ││ 直到得出最终答案│└─────────────────────────────────────────────────────────┘

实际例子:

问题:现在几点了?另外帮我算一下 (123 + 456) * 789Thought: 用户问了两个问题,需要调用两个工具Action: get_current_time()Observation: 2024011514:30:00Thought: 还需要计算数学表达式Action: calculator("(123 + 456) * 789")Observation: (123 + 456) * 789 = 456591Thought: 已经拿到所有信息,可以回答了Answer: 现在是202411514:30,(123 + 456) * 789 = 456591

3.4 create_react_agent 的魔力

LangGraph 提供了开箱即用的 Agent:

from langgraph.prebuilt import create_react_agentagent = create_react_agent(model=llm,tools=[calculator, get_current_time, ...],)# 直接用,Agent 自己搞定一切result = agent.invoke({"messages": [("human", "现在几点了?")]})

一行代码创建 Agent,它会自动:

3.5 工具设计原则

原则说明反例
单一职责一个工具只做一件事把计算和查询混在一起
描述清晰docstring 要让 AI 理解写得太简略
参数明确类型注解要准确用 Any 类型
错误处理返回有意义的错误信息直接抛异常

四、知识体系总结

通过这个项目,我形成了一个清晰的知识体系:

┌─────────────────────────────────────────────────────────┐│ LangChain + RAG + Agent│├─────────────────────────────────────────────────────────┤│ ││┌─────────────────────────────────────────────────┐ │││应用层│ │││智能助手 / 知识问答 / 自动化工具 │ ││└─────────────────────────────────────────────────┘ ││↑││┌─────────────────────────────────────────────────┐ │││编排层 (LangGraph)│ │││Agent / 工具调用 / 条件路由 / 循环重试│ ││└─────────────────────────────────────────────────┘ ││↑││┌─────────────────────────────────────────────────┐ │││能力层 (LangChain)│ │││Prompt / LLM / Chain / Retriever / Tools │ ││└─────────────────────────────────────────────────┘ ││↑││┌─────────────────────────────────────────────────┐ │││基础层│ │││向量数据库 / Embedding / 文档加载 │ ││└─────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────┘

五、学习建议

  1. 先跑通再理解:先把代码跑起来,看到效果,再深入理解原理
  2. 从简单到复杂:先搞懂 Prompt → Chain → Agent 的演进
  3. 动手改参数:修改 chunk_size、temperature 等参数,观察效果变化
  4. 读源码:LangChain 源码不难读,关键类就那几个

六、项目地址

下一篇:用 LangGraph 构建智能客服系统(零基础自学agent日记)

喜欢(0)

上一篇

企业AI知识库搭建指南:手把手带你落地

企业AI知识库搭建指南:手把手带你落地

下一篇

AIOps 落地失败复盘:多数团队智能化运维踩过的共性坑

AIOps 落地失败复盘:多数团队智能化运维踩过的共性坑
猜你喜欢