上下文学习:唯一重要的 AI 功能
停止微调吧。你的模型权重在训练完成的那一刻就已经过时了。上下文学习(ICL)才是真正的软件执行。
梯形图转SCL | AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace | Phot.AI | InVideo
你的提示词之所以有效,是因为你的模型具备从上下文中学习的能力。
你的 RAG 系统之所以能工作(即使它可能会产生幻觉),是因为大语言模型的上下文学习能力使其能够理解上下文。
你的 AI 代理之所以能工作,是因为它们将推理、计划和行动作为上下文学习层层叠加。
几乎每一个主要的应用新架构(或所谓的革命性功能)都只是对 ICL 的利用
我知道接下来的话会让很多机器学习工程师感到失望,坦白说,可能会冒犯到那些在定制微调上花费数万美元的人。
你的模型权重在训练完成的那一刻就已经过时了。
我们正在目睹一场全行业的幻觉。
高管和开发者们都深信,通往"更智能" AI 的道路是持续将专业知识直接烘焙到模型参数中。
他们将数百万 token 的内部公司文档倾倒进微调流水线,看着训练损失下降,然后庆祝……直到模型产生幻觉,虚构出一张客户发票,或者在训练集中没有出现的任务上失败。
如果你将参数更新视为主要的工作流引擎,那你误解了现代生成式 AI 的工作方式。
生成式 AI 最有前途、最强大、最令人惊叹的功能,不是微调、RAG 工具,也不是自主代理框架。
而是上下文学习(In-Context Learning,ICL)。
其他一切都只是建立在其上的包装。

1. 什么是 ICL(以及它为何改变一切)
想想当你雇佣一位经验丰富的高级工程师时会发生什么。
你不会在每个新项目开始时都送他们回大学再读四年。你会给他们一份详细的项目简报、规格和需求清单、两三个实际案例,然后说:"这就是我们今天需要完成的事情。"
他们不会为了理解你的简报而重写大脑中的物理神经通路:他们利用现有的基础知识,动态地、实时地处理你的指令。
这就是上下文学习。

ICL 是大语言模型学习新任务的能力,它纯粹从提示词提供的文本中采用特定的格式规则,并遵循复杂的操作指令:而无需更新其底层二进制文件中的单个权重。
而当你微调模型时,你是在修改其物理参数权重(W)。这相当于在主板上焊接新电路。它是永久性的、昂贵的且僵化的。
另一方面,ICL 完全在内存中运行。
如果我们将其转换为标准计算架构:
- 模型权重 = 硬盘驱动器。 预训练期间烘焙的世界知识的静态存储。
- ICL(提示词和 KV 缓存)= RAM。 实时逻辑、上下文和短期指令实际存在的动态运行时执行环境。
你不会为了打开文本编辑器而重新刷写计算机的 BIOS。
那么,为什么你要尝试微调一个 80 亿参数的模型,只是为了让它解析一个新的 JSON 模式呢?(我这里说的是泛指,不是特指你 😉)。
ICL 将大语言模型从静态查找数据库转变为可编程的软件运行时。

2. 意外发现:从微调到元学习
多年来,标准的自然语言处理范式很简单:取一个预训练模型如 BERT,编写一个特定任务的数据集,然后使用反向传播微调其参数(W)。
然后是 OpenAI 2020 年的开创性论文《语言模型是少样本学习者》(Brown 等人),介绍了 GPT-3。
研究人员注意到一种涌现现象:随着参数规模和预训练数据的扩展,Transformer 自然地发展出了仅通过在提示词中展示几个示例就能解决任务的能力。
在此之前,教条很简单:在文本上预训练,在目标数据集上微调。
GPT-3 证明了随着模型规模的扩大,它们成为与任务无关的元学习者。不需要梯度更新。
[传统微调] --> 更新模型权重 (W) --> 永久且昂贵
[上下文学习 (ICL)] --> 修改激活状态 --> 动态且临时
一个参数冻结的模型如何"即时"学习?天哪,即使到现在这对我来说也是一个真正的震撼!
机械可解释性研究人员在《上下文学习中是什么学习算法?》(von Oswald 等人)等研究中找到了答案。
在前向传播过程中,自注意力层构建的内部激活动力学在数学上镜像了梯度下降(一个被称为中间优化的概念)。
简单来说:Transformer 在阅读你的提示词时,在自己的内存激活中写入并更新一个临时的、隐式的迷你模型。
物理权重没有改变,但激活轨迹表现得就好像它是针对你的特定上下文实时训练的一样。

3. 主角:ICL 如何驱动现代 AI 工作流
一旦你意识到 ICL 是底层运行时,你就会开始在各处注意到它。
行业评论家喜欢每三个月就吹嘘"全新的范式转变"。但如果你深入研究,几乎每个主要的应用架构都只是对 ICL 的利用:
检索增强生成(RAG)
剥离其炒作成分,RAG 只是大规模的结构化 ICL。
向量数据库获取相关的文本块,ICL 在注入的上下文上执行零样本阅读理解,以在不产生所提供范围之外幻觉的情况下回答你的查询。
代理框架和函数调用
一个"AI 代理"循环只不过是一个持久的 ICL 上下文线程。
你向模型提供带有工具模式(JSON)的系统提示词,解析其结构化响应,在本地机器上执行函数,然后将执行输出粘贴回提示词窗口。
代理的整个推理链和记忆轨迹完全通过 ICL 存在。
思维链(CoT)和测试时计算
当你强制模型"逐步思考"时,你就是在利用 ICL。
实际上,通过向自己的提示词窗口生成中间推理 token,模型使用其过去的激活作为条件向量来解决复杂的逻辑依赖关系。

4. 长上下文谬误和本地解决方案
这把我们带到了大多数企业项目撞上现实的地方:项目管理三角。
当高管们看到现代模型号称拥有 100 万或 200 万 token 的上下文窗口时,他们假设旧的工程约束已经神奇地消失了。"为什么还要费心使用 RAG 或微调?"他们争辩道。"直接把整个公司文档文件夹倾倒进提示词窗口,让模型自己搞定就行了。"
拜托……清醒一点!
这种逻辑在物理和硬件追上你的幻灯片的那一刻就会崩溃。将巨大的上下文窗口视为无限倾倒场会触发两个灾难性故障:
- 二次计算墙(O(N²)): 标准自注意力随长度呈二次增长。当你的提示词从 10k 增长到 500k token 时,存储键值(KV)缓存所需的内存呈指数级爆炸。在消费级硬件或本地迷你 PC 上,这会立即导致内存不足崩溃或极慢的 token 生成速度。
- 注意力稀释("中间迷失"): 实证评估反复表明,当上下文延伸超过数十万 token 时,模型会遭受严重的检索退化。埋藏在大量上下文流中间的关键细节会被注意力弥散所淹没,将高容量提示词变成置信度很高的噪声生成器。
如果你通过 llama.cpp 等工具在消费级设置或集成显卡上运行本地 AI,你无法通过粗暴的上下文管理来暴力解决问题。
你需要某种外科手术般的精确度。
这里有一个在 llama.cpp 中被严重低估的原生功能,它可以在不增加 VRAM 的情况下解决 ICL 瓶颈。

5、提示词缓存(--prompt-cache)
为什么要强制你的 CPU/iGPU 在每次运行查询时重新评估相同的 5000 token 系统上下文或文档?llama.cpp 允许你将完全处理过的 KV 缓存直接保存到磁盘上的二进制状态文件中。
实际上,如果你使用 llama-server 的内置 web-ui,你已经在很好地利用提示词缓存了。如果你是 KV 缓存概念的新手,这里快速回顾一下。
键值缓存(KV Cache)是模型的短期记忆。每次你发送提示词时,模型都会计算注意力张量:这些是每个 token 在每个 Transformer 层中如何与其他 token 相关的数学表示。KV 缓存存储这些张量,这样模型就不必重新处理它已经见过的 token。
这样想:假设阅读一份 50 页的文档。没有 KV 缓存时,每次被问到关于第 49 页的问题时,你都必须从头重新阅读所有 50 页。有了 KV 缓存,你只需要阅读第 49 页——前 48 页已经在内存中了。
这就是 300ms 响应和 70ms 响应的区别。
6、在 web UI 中如何自动工作
当你使用内置 web UI 时,提示词缓存会透明地发生:
- Web UI 在客户端(浏览器 localStorage 或 IndexedDB)存储你的对话历史
- 每次你发送新消息时,UI 会将整个对话——每个之前的消息加上你的新消息——发送到
/v1/chat/completions端点 - 服务器的
cache_prompt功能(默认启用)检测新请求与该槽位上之前请求的公共前缀 - 只有新的后缀(你的最新消息)被处理——缓存的前缀从 KV 缓存中重用
- 响应包含
tokens_cached和prompt_n,这样你就可以看到跳过了多少 token
我在我的 Vulkan GPU 上使用 granite-4.0-350m、Q4_K_M.gguf 运行了一些测试,结果相当不错:
- 完整提示词:929 tokens
- 从缓存重用的 tokens:1,128(系统提示词 + 对话历史)
- 新处理的 tokens:62
- 结果:Time-To-First-Token 快 76.5%(290ms → 68ms)
7、为什么你需要 Python 脚本进行磁盘持久化
Web UI 只在 RAM 中缓存。关闭浏览器标签页,丢失缓存。重启服务器,丢失缓存。要实现跨会话的真正持久化,你需要使用服务器 API 显式地将 KV 缓存保存到磁盘。
但这里有一个问题,我在任何地方都找不到相关文档:服务器没有检索对话文本的端点。
保存/恢复端点只处理 KV 缓存张量,而不是你输入的消息。
这意味着你需要一个双重保存策略:

不保存对话文本,恢复 KV 缓存是毫无意义的。
事实上,当你发送新请求时,服务器会将提示词前缀与槽位的缓存提示词进行比较,以决定是否重用缓存。如果你从未发送过相同的对话文本(因为你只恢复了张量,而不是消息),相似性检查找不到匹配项,忽略缓存,然后从头开始处理所有内容。
你刚刚浪费了一个保存/恢复周期,却毫无收益。
8、自己试试看
学习某事的最好的方法就是自己动手。这里是你可以在启用提示词缓存的情况下运行 llama-server 的命令提示符。
llamacpp\llama-server.exe `
-m llamacpp\models\granite-4.0-350m-Q4_K_M.gguf `
-ngl 99 `
-c 16384 `
-np 1 `
--cache-type-k q4_0 `
--cache-type-v q4_0 `
--slot-save-path ./slot-cache `
--cache-reuse 256 `
--cache-prompt `
-sps 0.0 `
--slots `
--metrics `
--host 127.0.0.1 `
--port 8080
如果你好奇但不想阅读 llama-server -h,这里是各标志的解释:

现在,想象你正在使用一个 Python 应用,你还希望能够保存对话历史,这样你就可以从上次中断的地方继续,比如明天。你应该怎么做?
这里是保存/恢复流程的示例:
from openai import OpenAI
import requests, json
client = OpenAI(base_url="http://localhost:8080/v1", api_key="dummy")
# --- 保存会话 ---
# 1. 发送对话(服务器自动缓存 KV 状态)
response = client.chat.completions.create(
model="local-model",
messages=messages,
extra_body={"cache_prompt": True, "id_slot": 0}
)
# 2. 将 KV 缓存张量保存到磁盘
requests.post("http://localhost:8080/slots/0?action=save",
json={"filename": "session.bin"})
# 3. 将对话文本保存到磁盘(客户端责任)
with open("session.json", "w") as f:
json.dump(messages, f)
# --- 恢复会话(稍后,服务器重启后) ---
# 1. 从磁盘恢复 KV 缓存张量
requests.post("http://localhost:8080/slots/0?action=restore",
json={"filename": "session.bin"})
# 2. 从磁盘加载对话文本
with open("session.json") as f:
messages = json.load(f)
# 3. 继续聊天——缓存会自动重用
response = client.chat.completions.create(
model="local-model",
messages=messages + [{"role": "user", "content": "Now what?"}],
extra_body={"cache_prompt": True, "id_slot": 0}
)
结果如何? 接近零的 Time-To-First-Token(TTFT)延迟和零冗余计算——无需重新处理单个缓存的 token。
9、结论:你的经验仍然是驱动力
如果你的主张让你失望,因为你曾希望 AI 能自动化地消除对严格系统架构或人类领域知识的需求,那很好。
ICL 是一个高性能的引擎,但它完全依赖于掌握方向盘的操作员。
向 ICL 窗口中输入糟糕的上下文,你会得到快速而自信的垃圾。
是时候掌握运行时,按照你自己的方式构建,并将 AI 视为其本来面目:你的 AI,你的规则。
原文链接:Believe it or not, In-Context Learning is the only AI feature that matters.
汇智网翻译整理,转载请标明出处