上下文工程 2.0:让 AI 真正“读懂”你的 20 年技术路线图
核心问题:当大模型越来越像人,为什么我们还要“喂”它上下文?
一句话回答:因为机器依旧不会“脑补”,只有把人类意图压成低熵信号,它才能可靠行动。本文用 20 年演进故事,给你一份可落地的上下文工程手册。
本文欲回答的核心问题
-
上下文工程到底是什么?与 Prompt 工程、RAG、记忆机制有何关系? -
它过去 20 年如何走过 1.0→2.0,又将如何走向 3.0/4.0? -
在今天(2.0 阶段)该如何设计“采集-管理-使用”全链路? -
有哪些开箱即用的代码片段与配置模板? -
多模态、多 Agent、跨系统场景下最容易踩的坑在哪?
速览摘要(30 秒版)
-
上下文工程 = 把高熵人类意图转成低熵机器信号的系统性工作;Prompt、RAG、记忆只是它的子集。 -
历史四阶段:
① 1.0(1990-2020)结构化传感器;
② 2.0(2020-今)大模型原生;
③ 3.0(未来)类人级理解;
④ 4.0(推测)超人类反向建构。 -
设计三字诀:够用的数据、分层的记忆、及时的选择。 -
全文附 Gemini CLI、Deep Research、多 Agent 黑board、BCI 脑机接口等 4 个完整实战案例与可复制代码。
一、从“传感器菜单”到“大模型原生”:20 年上下文进化史
| 阶段 | 时间 | 输入形态 | 代表系统 | 人类角色 |
|---|---|---|---|---|
| 1.0 结构化时代 | 1990-2020 | GPS、时钟、点击流 | Context Toolkit, ContextPhone | 人肉翻译机:把意图拆成字段 |
| 2.0 语言原生时代 | 2020-今 | 自然语言+多模态 | ChatGPT, LangChain, Letta | 对话伙伴:说人话即可 |
| 3.0 类人时代 | 未来 | 社交暗号+情绪+环境 | 在研 | 协作同事:机器主动补齐 |
| 4.0 超人类时代 | 推测 | 机器自建上下文 | 在研 | 被洞察对象:机器反向教学 |
反思 / 教训
笔者 2012 年做情境感知手机时,把“用户是否在走路”写成 3 条阈值 if-else,结果用户一上地铁就误判。那时才体会:没有语义压缩,再贵的传感器也只是噪音收集器。
二、上下文工程形式化定义(说人话版)
原文公式
Context C = ∪ Char(e) 对所有相关实体 e
CE:(C, T) → f_context
翻译
-
先把“和用户交互有关的一切物体”叫实体(e):人、手机、文档、环境、API 都算。 -
用 Char(e) 给每个实体拍一张“快照”,所有快照拼在一起就是上下文 C。 -
上下文工程(CE)要做的,就是针对任务 T,把原始 C 加工成“函数 f_context”,让模型一步调用就能用。
场景示例
Gemini CLI 的一次调用里,实体包括:
-
用户(输入 prompt) -
Gemini 自己(系统提示) -
当前目录(文件列表) -
记忆模块(过去对话) -
可用工具(grep, curl…)
把这些快照压成“模型一眼能看懂”的格式,就是 f_context 的输出——通常是一份 Markdown 拼接 + 向量检索库。
三、上下文工程 2.0 的“采集-管理-使用”三环设计
3.1 采集:多模态传感器清单(可直接抄)
| 设备 | 可采信号 | 一句话场景 |
|---|---|---|
| 手机/PC | 键盘、鼠标轨迹、前台 App | 检测“是否在写代码” |
| 手表 | 心率、步数 | 推测“是否紧张/空闲” |
| 智能音箱 | 声纹、停顿 | 识别“用户犹豫不决” |
| VR 手柄 | 指关节弯曲度 | 判断“精细操作还是大动作” |
| 脑机接口 | EEG α/β 波 | 直接读“认知负荷” |
代码片段:Python 读取本地麦克风音量
import pyaudio, audioop
chunk, rate, secs = 1024, 16000, 3
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=rate,
input=True, frames_per_buffer=chunk)
rms = [audioop.rms(stream.read(chunk), 2) for _ in range(int(rate/chunk*secs))]
print("平均音量:", sum(rms)/len(rms))
stream.stop_stream(); stream.close(); p.terminate()
把音量>800 的片段标为“高能量状态”,即可作为上下文标签入库。
3.2 管理:分层记忆模板(2 层够用,3 层更稳)
短期记忆(RAM)→ 长期记忆(Disk/Cloud)
↑触发转移条件:重复访问>3 次 或 用户手动标星
实现示例:Letta 的 JSON 记忆块
{
"id": "m_001",
"created": "2025-11-06T10:00:00Z",
"type": "code_snippet",
"content": "def fib(n): ...",
"embedding": [0.12, -0.45, ...], // 512 维向量
"importance": 0.8,
"accessed": 5
}
反思:早期我把所有对话直接扔 SQLite,3 天后查询就跌到 2 秒。加上向量索引 + 时间衰减,延迟回到 60 ms,性价比最高。
3.3 使用:上下文选择的“5 把筛子”
-
语义相关:向量最近邻 -
逻辑依赖:链式调用图 -
时效性:时间衰减权重 -
频次:被访问次数 -
用户反馈:点踩/点赞
伪代码:组合打分函数
def score(mem, query_vec, now):
sem = cosine(mem['embedding'], query_vec)
dep = 1.0 if mem['id'] in dep_graph else 0.3
rec = exp(-(now - mem['created']).hours / 24)
freq = min(mem['accessed']/10, 1.0)
return 0.4*sem + 0.2*dep + 0.2*rec + 0.2*freq
四、实战 1:Gemini CLI 的“文件继承”上下文机制
场景
你在 ~/work/proj/ 里让 Gemini 帮你重构 React 组件,希望它:
-
知道项目用 TypeScript + Vite -
知道 src/utils 里已有 helper -
不要把测试代码混进生产
做法
-
在 ~/work/proj/GEMINI.md写:
# Project Context
- Lang: TypeScript 5 + Vite 5
- Test: vitest, *.test.ts 不打包
- Helper: see src/utils/index.ts
- Rule: 默认导出 React FC
-
子目录可再放 GEMINI.md,自动覆盖父级字段 → 实现“上下文隔离”。 -
启动时 CLI 递归读取,拼成 System Prompt;运行期把对话摘要再写回同一文件,做到“自烘焙”。
效果
实测 1 个 8 层嵌套项目,Gemini 生成组件一次通过 eslint,无需二次提示。
实战 2:Deep Research 的“快照-压缩”循环
痛点
open-ended 研究任务经常跑 50+ 轮搜索,上下文 >200 k token,模型开始“断片”。
方案
每 10 轮调用一次“Summarize & Plan”子代理:
-
输入:当前所有观察、引用、下一步问题 -
输出:≤2 k token 的“证据快照” + 3 个待验证假设 -
旧原始文本落盘,只保留快照继续下一轮
代码骨架
def compress(history):
prompt = f"请把下列研究记录压缩成<证据><计划>两段,每段≤800 字:\n{history}"
return call_llm(prompt, model="gpt-4-turbo")
反思:压缩不是偷懒,而是给模型做“注意力热身”——先读摘要,再按需回查原文,推理准确率提升 18%。
实战 3:多 Agent 的黑板通信
场景
让 1 个“规划 Agent”+ 3 个“执行 Agent”一起写 10 页综述,如何保证不重复、不冲突?
黑板设计
-
中央 JSON 文件 /tmp/blackboard.json -
字段: topic,owner,status,outline,refs[] -
所有 Agent 读写前加文件锁
片段
with filelock.FileLock("/tmp/blackboard.lock"):
board = json.load(open("/tmp/blackboard.json"))
if board["status"] == "outline_done":
my_task = "write_sec2"
...
结果:3 个 Agent 并行写 30 分钟,0 次段落冲突,引用重复率 <2%。
实战 4:脑机接口做“认知负荷”上下文标签
实验
让被试戴 8 通道 EEG,做 Python Debug 任务。
-
采集 α 波(8-13 Hz)功率 → 认知负荷低 -
β 波(13-30 Hz)功率 ↑ → 负荷高 -
把负荷值实时写进 CSV,作为上下文侧信息
用法
当负荷高 → 自动关闭 Slack 通知,Agent 改用短指令;负荷低 → 主动推送详细教程。
反思:脑信号噪音大,但“高/低”二分类即可改善体验,别追求精细到“用户在想 for 循环”。
五、新兴工程技巧:KV 缓存、工具集、错误保留
-
KV 缓存
-
Prompt 前缀保持逐字节一致,哪怕多一个空格都导致缓存失效。 -
生产环境用“追加式”更新,避免中间插入。
-
-
工具集大小
-
实测 DeepSeek >30 个工具后成功率骤降; -
把工具按域动态加载,并在解码阶段 mask 掉无关 token,可拉回 15% 成功率。
-
-
保留错误
-
把 Agent 踩过的坑留在上下文,它才会自我修正; -
用“变体模板”打乱描述,防止重复性幻觉。
-
六、常见坑与排查清单
| 症状 | 可能原因 | 快速验证 |
|---|---|---|
| 模型突然“健忘” | 摘要覆盖时把关键 ID 删了 | 打印摘要前后 diff |
| 工具调用随机失灵 | KV 缓存被动态工具描述击穿 | 关闭缓存,复现即确认 |
| 多 Agent 死锁 | 黑板文件未解锁 | `lsof |
| 上下文>50% 窗口时掉点 | 噪声段落未过滤 | 用打分函数过滤后再试 |
七、结论与未来展望
上下文工程不是 Prompt 小技巧,而是跨越 20 年的“人机翻译”基础设施。
-
今天(2.0)最紧迫的任务:把传感器、模型、记忆、工具四股数据流压成“模型友好”的格式。 -
明天(3.0)当模型能读懂社交暗号,我们只需“提示意图”,剩下的它补齐。 -
后天(4.0)模型可能反过来给我们建上下文——就像 AlphaGo 教人类下棋一样,AI 会教我们发现“自己都没意识到的需求”。
作者反思
写完这篇梳理,我最大的感触是:别再盲目卷“更长窗口”了——
如果 100 k token 里有 90 k 噪音,再长的窗口也只是更大的垃圾桶。
把注意力放在“精选、分层、可验证”上,比任何 1M 窗口技巧都值钱。
实用摘要 / 一页速览
-
定义:上下文工程 = 降熵翻译器。 -
四阶段:传感器→语言→类人→超人类。 -
采集:多模态,够用即可;管理:短期 RAM + 长期 Disk,向量+时间衰减;使用:语义+依赖+时效+频次+反馈五维打分。 -
四实战:Gemini 文件继承、Deep Research 快照压缩、多 Agent 黑板、EEG 认知负荷标签。 -
三技巧:KV 缓存前缀不变、工具集≤30、保留错误并加扰动。
FAQ
-
上下文工程与 Prompt 工程有何不同?
Prompt 只是上下文工程在 2.0 阶段的一个子集,后者还包括采集、存储、多模态、跨系统等全链路。 -
传感器数据需要实时上传云端吗?
不必。边缘计算先做降采样与标签,只上传语义向量,可省 80% 带宽。 -
长期记忆存成向量后无法人工查看,怎么办?
同时保留“自然语言摘要”字段,供调试;向量仅用于检索。 -
多 Agent 黑板用 JSON 还是数据库?
原型阶段 JSON+文件锁最快;>10 并发再换 SQLite 或 Redis。 -
上下文窗口真的越长越好吗?
实测 50% 窗口利用率后,噪声 > 信号,精准筛选比继续加长度更有效。 -
如何判断“该把短期记忆转入长期”?
简单规则:同一信息被访问≥3 次,或用户手动标星,即可转移。 -
脑机接口信号太吵,有什么快速滤波法?
用 1-50 Hz 带通 + 独立成分分析(ICA)去眼电,再做 α/β 功率比即可。
