跳到主要内容

扩展 LLM 的能力边界:联网搜索、文件读写与记忆功能全景指南

· 阅读需 10 分钟

引言​

上一篇我们聊了 Function Calling 诞生的背景——LLM 为什么必须学会调用函数。这篇更进一步,把问题摊开:

一个只会输出文本的模型,如何长出"眼睛"、"手"和"记忆"?

  • 联网搜索给它眼睛,让它看到训练数据截止之后的世界;
  • 文件读写给它手,让它能在真实工作环境中留下成果;
  • 记忆功能让它跨越会话,记住你是谁、上次做到哪一步。

这三项能力,加上代码执行和 MCP 协议的标准化,构成了今天所有 AI Agent 的地基。本文逐项拆解它们的原理、实现路径和工程上的坑。


TL;DR​

LLM 的能力扩展,本质是同一个模式:把外部能力封装成工具,让模型决定何时调用,执行结果再回到上下文。

能力解决什么问题核心实现
联网搜索知识有截止日期、幻觉Web Search API + RAG
文件读写无法操作真实工作环境文件系统工具 + 沙箱隔离
代码执行算不准、不能验证Code Interpreter / Bash 沙箱
记忆功能关掉窗口就失忆短期记忆 + 长期记忆(向量库 / 结构化文件)
MCP工具接入碎片化标准化协议,一次开发到处可用

一切扩展的基础:工具调用循环​

无论扩展哪种能力,底层都是同一个循环(ReAct 模式的简化版):

用户提问
↓
模型判断:需要外部能力吗?
↓ 是
生成工具调用请求(函数名 + 参数 JSON)
↓
宿主程序(Harness)真正执行工具
↓
执行结果注入上下文
↓
模型基于结果继续推理 / 再次调用工具 / 给出最终回答

关键认知:模型本身从不执行任何操作。 它只生成"我想调用 search_web(query='...')"这样的结构化文本,真正干活的是模型外面的宿主程序。模型是大脑,工具是感官和四肢,宿主是连接它们的神经系统。

理解这一点,后面每一项能力扩展都只是"往工具箱里放一件新工具"。


一、联网搜索:打破知识的截止日期​

为什么需要​

LLM 的训练数据有截止日期。问它"今天的股价"、"最新的 API 文档"、"这个 CVE 漏洞的细节",它要么编造,要么承认不知道。而搜索引擎背后是实时索引的整个互联网。

两种实现路径​

路径一:模型内置搜索(Search as a Tool)

模型厂商把搜索做成官方工具:模型自主决定搜索关键词,平台执行后把结果喂回去。优点是零接入成本;缺点是搜索源和质量不可控,且通常按次计费。

路径二:自建 RAG 检索管道

def search_web(query: str, top_k: int = 5) -> list[dict]:
"""自定义搜索工具:搜索 → 抓取正文 → 截断摘要"""
results = search_engine.query(query, limit=top_k) # Bing/Google/Tavily/SearXNG
return [
{
"title": r.title,
"url": r.url,
"snippet": fetch_and_extract(r.url)[:2000] # 控制 token 消耗
}
for r in results
]

自建的价值在于可控性:你可以限定搜索源(比如只查内部文档站)、决定摘要长度、做去重和时效过滤。

工程上的三个坑​

  1. 上下文爆炸:一个网页正文可能上万 token,直接塞进上下文既烧钱又稀释注意力。必须做正文提取和截断。
  2. 时效标注:搜索结果要带上抓取时间,模型才能判断"这条信息是否新鲜",否则它可能拿三年前的价格回答今天的问题。
  3. 来源引用:要求模型给出信息来源 URL,既是可验证性的要求,也能显著降低幻觉率。

二、文件读写:给模型一个真实的工作环境​

为什么需要​

没有文件系统,LLM 产出的一切都只是对话窗口里的文字——关掉就没了。有了文件读写,它才能:

  • 把中间结果落盘,突破上下文窗口限制(写出去,需要时再读回来);
  • 直接操作项目代码、文档、数据文件,产出可用的交付物;
  • 多个 Agent 之间通过文件协作(文件即共享白板)。

最小实现​

def read_file(path: str) -> str:
"""读取文件内容"""
return Path(sandbox_root, path).read_text(encoding="utf-8")

def write_file(path: str, content: str) -> str:
"""写入文件,返回确认信息"""
target = Path(sandbox_root, path)
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(content, encoding="utf-8")
return f"已写入 {path}({len(content)} 字符)"

加上 list_files、edit_file(精确替换,比全量重写省 token)、search_files(grep),就是一个够用的文件工具集。

三个必须做的防护​

  1. 路径沙箱:所有路径必须限制在工作区根目录内,拒绝 ../ 越界。模型生成的路径不可信。
  2. 读写分离:读取相对安全,写入要有分寸——大文件截断读、二进制文件拒绝、敏感文件(.env、私钥)黑名单。
  3. 变更可回滚:配合 Git,让模型大胆改,人类一键回滚。文件系统 + Git = 模型的试错空间。

三、代码执行:从"会说"到"会做"​

严格说这不是用户点名的能力,但它是文件读写的天然搭档,值得一并讲。

模型心算三位数乘法都经常出错,但它写的代码可以算得很准。代码执行把模型从"估算器"变成了"真正的计算器 + 实验员":

  • 数据分析:写 pandas 脚本处理 CSV,而不是逐行"心算";
  • 自我验证:写完代码跑一遍,报错了自己修——这是 Agent 能迭代进步的关键;
  • 产出真实交付物:生成的图表、报表直接保存为文件。

实现上通常是 Code Interpreter(受控 Python 环境)或 Bash 工具 + 容器沙箱。安全是头等大事:沙箱内不挂载敏感目录、限制网络访问、限制 CPU/内存/时长,必要时用 rootless 容器或微 VM。


四、记忆功能:跨越会话的连续性​

为什么需要​

LLM 的上下文窗口就是它的全部"工作记忆"。窗口之外,一片空白。没有记忆系统,每次对话都从"你好,我叫……"重新开始,复杂的长期项目根本无从谈起。

记忆不是单一技术,而是一套分层体系:

第一层:短期记忆(上下文内)​

当前会话的对话历史,模型的"工作台"。管理重点是上下文工程:该保留什么、压缩什么、丢弃什么。长会话中常见的做法是滑动窗口 + 摘要压缩——把前面的对话总结成几段摘要,只保留最近几轮原文。

第二层:长期记忆(跨会话持久化)​

两种主流形态,各有利弊:

① 向量记忆(语义检索派)

def memory_search(query: str, top_k: int = 5):
"""语义检索:把过往对话/笔记向量化,按相关度召回"""
embedding = embed(query)
return vector_db.similarity_search(embedding, k=top_k)
  • 优点:召回语义相关的内容,即使用词完全不同
  • 缺点:是"黑盒",难以审计模型到底记住了什么;过期信息难清理

② 结构化文件记忆(笔记派)

让模型像人一样记 markdown 笔记:

memory/
├── user-profile.md # 用户偏好、习惯、项目背景
├── decisions.md # 做过的关键决策及原因
└── projects/
└── blog-rewrite.md # 每个项目一份进展笔记
  • 优点:完全透明、可编辑、可 Git 版本化;人能直接看到 AI"记得"什么
  • 缺点:依赖模型自觉维护,检索靠文件索引而非语义匹配

工程实践中两者常混用:重要事实写结构化笔记,海量历史对话进向量库,启动会话时加载笔记 + 按需检索向量库。

记忆工程的两个关键设计​

  1. 记忆写入策略比读取更难。什么值得记?常见规则:用户明确说"记住这个"、纠正过模型的错误、跨会话仍有效的偏好。什么都记 = 记忆库变成垃圾场,召回质量直线下降。
  2. 遗忘和更新必不可少。偏好会变("我现在改用 pnpm 了"),记忆必须支持更新和过期,否则旧记忆会和新指令打架。

五、MCP:让工具生态标准化​

前面讲的每一项能力,传统做法都是在自家代码里手写工具定义、手写 JSON Schema、手写执行逻辑。换个 Agent 框架就得重写一遍。

Model Context Protocol(MCP) 是 Anthropic 在 2024 年底开源的协议,思路类似编程语言里的 LSP(Language Server Protocol):

传统模式: Agent A ──┐
Agent B ──┼── 各自实现一套 GitHub / 数据库 / 文件系统接入
Agent C ──┘

MCP 模式: 任意 Agent ──统一协议── MCP Client ── MCP Server(GitHub)
├─ MCP Server(Postgres)
└─ MCP Server(文件系统)
  • 工具提供方只写一次 MCP Server,所有兼容 MCP 的 Agent 都能用;
  • Agent 开发方只需实现 MCP Client,瞬间接入整个工具生态;
  • 工具列表在运行时动态发现,不用硬编码。

2025 年以来,OpenAI、Google 相继宣布支持 MCP,它已经成为事实上的工具接入标准。对开发者意味着:写工具的价值被放大了——你写的 MCP Server 不再绑定某一家 Agent。


组合起来:从工具到 Agent​

单项能力是零件,组合起来才是机器。一个能干活的研究型 Agent 的典型工作流:

  1. 收到任务"调研 XX 技术并写一份报告";
  2. 记忆:加载用户偏好(报告要中文、要有 TL;DR);
  3. 联网搜索:多轮搜索、交叉验证、记录来源;
  4. 文件读写:调研笔记先落盘,分段写报告;
  5. 代码执行:做一张对比图表;
  6. 产出报告文件,更新记忆("用户对上一版报告的反馈是……")。

这就是 Agent 的本质:LLM + 工具 + 记忆 + 循环,缺一不可。


工程实践清单​

如果你要给自己的应用加上这些能力,按这个顺序来:

  • 先上工具调用循环——这是所有能力的地基,别跳过
  • 联网搜索——解决幻觉和时效,收益最快见效
  • 文件读写 + 沙箱——打开生产力场景,但先把路径隔离和黑名单做好
  • 代码执行——配合文件能力,让模型能自我验证
  • 记忆分层——短期靠上下文工程,长期先上结构化笔记,量大了再补向量库
  • 工具协议向 MCP 靠拢——新工具直接写成 MCP Server,避免锁定
  • 全程可观测——记录每一次工具调用的输入输出,这是调试和信任的基础

结语​

回头看,LLM 能力扩展的历史就是一部"给大脑接器官"的历史:

  • 搜索让它看到现在,
  • 文件让它触摸世界,
  • 代码让它验证自己,
  • 记忆让它拥有过去,
  • MCP 让这一切标准化、可复用。

模型负责推理,工具负责感知和行动,记忆负责连续性。三者齐备,"聊天机器人"才真正变成了"数字员工"。


相关阅读