跳转到内容

第 5 节 · LLM + 外部支持:RAG、工具与上下文工程

LLM 的"天生不知道"

LLM 被关在玻璃罩里,四类信息它够不到

回忆第 1 节的类比:LLM 就像一个住在图书馆里、读过很多书但没有手机的人。只调用裸模型 API 时,下面四类信息它无法可靠获得:

类型例子
实时信息现在几点 / 今天天气 / 某只股票的当前价格
私域知识你公司的内部文档 / 你仓库里的代码
训练截止后的事最新的新闻、论文、政策
执行结果跑一段代码会输出什么 / 调一个 API 返回什么

不管模型多大、多聪明,这四类信息都不应该靠"模型参数里会不会碰巧记得"来解决。工程上更可靠的做法是:把信息放进上下文,或者让模型调用工具去获取。

NOTE

这里说的是裸模型 API(如 chat.completions.create)。商用产品(ChatGPT、Gemini、Perplexity 等)通常已帮你接好搜索、代码执行等工具,所以用户感知上模型"好像什么都知道"——但底层仍然是"模型 + 工具"的组合。

2026 关键词:Context Engineering

现在业界越来越常用 Context Engineering(上下文工程) 来概括这件事:不是只写一句 prompt,而是系统地决定模型每次能看到什么、能调用什么、历史怎么压缩、结果怎么验证。RAG 和 Tool Use 都是上下文工程的一部分。

方式 1:把相关信息塞进 Prompt(朴素 RAG)

最直接的解法:你手动把外部信息拼进 user message,让模型基于它来回答。

python
# 示例:让模型回答内部政策问题
internal_doc = open("internal_policy.md").read()

messages = [
    {"role": "user", "content": f"""
请根据以下内部文档回答问题。

【文档内容】
{internal_doc}

【问题】
报销流程是什么?
"""}
]

模型本来不知道你公司的报销流程,但你把资料喂给它了,它就能准确回答。

这就是 RAG(Retrieval-Augmented Generation,检索增强生成) 的最朴素版本:

  • Retrieval(检索):你手动找到相关文档
  • Augmented(增强):把文档塞进 prompt
  • Generation(生成):模型基于文档生成回答

更完整的 RAG 系统一般会自动完成这条流水线:

bash
用户问题 检索知识库 取回相关片段 拼进上下文 LLM 基于证据回答

优点

  • 简单粗暴,立竿见影
  • 任何 LLM 都支持(只要支持 chat 接口)
  • 可以要求模型给出引用,方便回到原文核查

缺点

  • 需要你手动决定塞什么信息
  • 信息量大时会撑爆上下文窗口(回忆第 3 节)
  • 模型自己无法主动"去找"它需要的信息
  • 检索错了,模型会基于错误上下文认真回答
  • citation 只能帮助核查,不等于答案一定正确

2026 年生产级 RAG 很少只做"向量库 top-k 检索"。常见做法会加入关键词检索、重排序、权限过滤、来源追踪、低置信度拒答等环节。

方式 2:让 LLM 自己调工具

更进一步:不是"你帮模型找信息",而是让模型自己决定该查什么工具

这里的"工具"不是让模型随便访问世界,而是你的程序暴露出来的一组受控函数。它们大致分两类:

类型例子特点
查询型工具搜索、读文件、查数据库、取当前时间把外部信息带回上下文
行动型工具发邮件、下订单、改文件、调用业务 API真的改变外部世界,必须更谨慎

流程大致是这样的:

用户: "现在是北京时间几点?"

LLM 思考: "我不知道当前时间,但我有一个 get_current_time 工具可以用"

LLM 输出: tool_call: get_current_time()

你的程序执行工具,拿到结果: "2026-05-25 15:20:00 北京时间"

把结果传回给 LLM

LLM 组织自然语言回复: "现在是北京时间 15:20。"

返回给用户

这就是 Agent 的雏形——模型不再是被动等你喂信息,而是主动伸手向外部世界获取信息

Day2 会详细实现这套机制(Function Calling 协议)。今天先理解"为什么需要它"。

工具标准化:MCP

Anthropic 在 2024 年底开源了 MCP(Model Context Protocol)。到 2025-2026 年,它已经成为 AI 应用连接外部工具和数据源的重要开放标准。MCP 定义了一套统一的工具、资源和提示模板接口,让同一套能力可以被不同客户端复用——类似于"USB 接口标准"让不同设备能插同一根线。

本课程的 Function Calling 实现与 MCP 的核心思想一致(工具注册 → 模型选择 → 执行 → 返回结果)。先学会最小工具调用,后面再理解 MCP 会轻松很多。

两种方式的对比

朴素 RAG vs 工具调用:人喂资料 vs AI 自己伸手

朴素 RAG(塞进 prompt)Tool Use(模型自己调)
谁决定查什么开发者/检索系统模型自己
灵活性低(写死了查什么)高(模型按需选择)
复杂度极低需要实现工具调度
适用场景固定文档问答、政策解释、资料总结实时查询、精确字段、执行动作
主要风险检索不到 / 检索错 / 上下文太长选错工具 / 参数错 / 行动越权

在实际工程中,两种方式经常组合使用,这种融合常被称为 Agentic RAG

  • 模型自己决定什么时候需要检索、检索什么关键词
  • 检索不到时自动切换到其他工具(搜索引擎、代码执行、API 调用)
  • 检索到的内容不够好时,模型会重新构造查询再试一次

传统 RAG 是"开发者写死检索逻辑",Agentic RAG 是"模型自主驱动检索循环"——后者正是本课程要构建的 Agent 能力。

但 Agentic RAG 不是魔法。它仍然需要权限控制、循环上限、结果核查和可观测日志,否则就会变成"模型带着工具乱跑"。

核心类比:LLM 是大脑,工具是手脚

角色类比
LLM一个聪明但被关在房间里的人——能推理、能总结,但看不到外面
工具给他一部手机(查天气)、一个文件柜(读文档)、一台电脑(跑代码)
Agent聪明人 + 一套工具 + "自己决定该用哪个" 的能力

整个 Agent 开发的核心工作就是

  1. 给 LLM 配什么工具
  2. 怎么描述这些工具让 LLM 能正确选择
  3. 怎么管理上下文不让它爆
  4. 怎么限制危险动作、验证工具结果并记录日志

动手试试

运行 demo_05_with_tool.py,会看到两组前后对比实验:

实验 1:内部知识

  • ① 直接问"课程截止时间" → 裸模型没有这份内部文档
  • ② 把内部文档塞进 prompt → 模型立刻精确回答

实验 2:当前时间

  • ① 只问 LLM"现在几点" → 它无法从参数里知道当前时间
  • ② 给它 get_current_time() 工具 → 模型自己决定调用工具再回答

看到的关键结论:LLM 不是不能解决这些问题——它只是需要可靠上下文,或者需要受控工具去获取上下文。

回顾:Day1 的完整拼图

1. Next-token prediction  解释了 LLM "怎么思考"
2. 三种角色 + messages 协议  解释了 "怎么跟它说话"
3. Token + 上下文窗口  解释了 "成本与物理限制"
4. 幻觉  解释了 "它的弱点"
5. 外部支持  解释了 "怎么补强弱点" 通往 Agent

Day1 完整回答了"LLM 是什么、能做什么、不能做什么"

从 Day2 开始,我们把第 5 节中"手动喂信息"的过程自动化——让 LLM 自己决定调哪个工具、怎么调、调完怎么用。这就是 Function Calling 协议,也是 Agent 的核心机制。

小结

概念一句话理解
LLM 的天然边界不知实时、不知私域、不知训练后的事、不能执行
朴素 RAG手动把信息塞进 prompt
Tool Use让 LLM 自己决定调什么工具
Context Engineering管理模型能看到、能调用、能记住和能验证的信息
MCP连接模型应用与外部工具/数据源的开放协议
AgentLLM + 工具 + 自主决策能力

下一步(Day2):实现 Function Calling——让 LLM 自己选工具、调工具、用结果回答用户。

Released under the MIT License.