Context Engineering 到底是什么
很多人第一次接触 LLM 应用时,会把注意力放在 Prompt 上:怎么写一句更有效的指令,怎么让模型更听话,怎么让回答更稳定。
这些当然重要,但当应用从 Demo 走向真实产品后,你会发现决定输出质量的往往不是某一句 Prompt,而是模型这次到底看到了什么。
它有没有看到当前页面状态?有没有看到用户权限?有没有看到最近对话?有没有看到业务规则?有没有看到检索文档?有没有被旧消息、脏数据、无关日志或错误工具结果干扰?
Context Engineering 讨论的就是这些问题。
它不是“写更长的 Prompt”,而是把模型输入当作一条工程流水线:从多个来源收集信息,按权限过滤,按任务排序,按预算裁剪,按优先级合并,最后构造成模型可以使用的上下文。
为什么前端工程师要理解它
前端工程师天然熟悉“上下文”。
一个按钮是否可点,不只取决于按钮文案,还取决于登录状态、表单校验、用户角色、网络请求、A/B 实验和当前页面数据。一个组件渲染成什么样,也不只取决于 props,还受全局 store、路由、主题、权限和异步状态影响。
LLM 应用也是一样。用户输入只是触发事件,模型真正的行为由完整上下文决定。
例如用户在项目管理工具里说:“总结一下风险。”
这句话本身几乎没有信息量。系统至少要决定:
- 用户当前在哪个项目。
- 当前选中的迭代是哪一个。
- 哪些任务被阻塞。
- 哪些数据用户有权限查看。
- 是否要参考历史讨论。
- 是否要引用知识库规则。
- 输出是展示在页面里,还是写入周报草稿。
这些决策很多都发生在前端和后端协作的边界上。前端负责表达页面状态、用户选择、引用对象和交互意图;后端负责汇总、过滤、组装和调用模型。不了解 Context Engineering,前端很容易把 AI 功能做成“一个输入框加一个接口”,最后遇到质量问题却无从定位。
Context 和 Prompt 的关系
Prompt 是模型输入的一部分,但 Context Engineering 比 Prompt 更大。
Prompt 更像一份指令文本,告诉模型“你是谁”“要做什么”“如何输出”。Context 则包括这次生成所需的所有信息:系统规则、用户输入、历史消息、页面状态、业务数据、检索片段、工具结果、用户偏好、权限边界和输出协议。
可以把它们理解成这样的关系:
Prompt Engineering 关注“如何表达任务”。Context Engineering 关注“模型应该基于哪些信息完成任务”。两者不是互斥关系,而是包含关系。一个成熟 AI 应用通常会有稳定的 Prompt 模板,同时有独立的上下文组装系统。
Context Engineering 的核心问题
Context Engineering 至少要回答六类问题。
第一,信息从哪里来。
上下文来源可能包括系统提示词、用户当前输入、历史消息、对话摘要、当前页面状态、后端业务数据、检索结果、工具返回、用户画像、组织配置和实验开关。不同来源的可靠性、时效性和敏感程度都不同。
第二,哪些信息允许进入。
模型不应该看到用户无权访问的数据,也不应该收到无关的敏感字段。比如一个客服助手可以看到订单状态,但不一定应该看到完整身份证号、支付令牌、内部风控备注。
第三,哪些信息对当前任务有用。
同一个用户的长期偏好,不是每次都要注入。用户喜欢“简洁回答”,对写邮件有用;对执行退款规则校验可能无关。最近十轮对话也不一定都重要,早期确认的目标可能比最近的寒暄更关键。
第四,信息之间如何排序。
LLM 对上下文顺序敏感。系统边界、任务目标、业务规则、输入数据和输出协议最好有稳定结构。把所有材料混在一个大字符串里,会让模型更难判断优先级。
第五,超过 Token 预算怎么办。
上下文窗口不是垃圾桶。历史消息、文档片段、工具结果和输出空间都在竞争 token。超长时应该有明确策略:先丢弃低价值历史,还是压缩工具结果?先保留系统规则,还是保留用户输入?这些不能临时靠字符串长度截断。
第六,如何观测和调试。
如果用户说“模型忘了前面说过的要求”,你需要知道这条要求有没有进入本次上下文。如果回答引用了错误文档,你需要知道检索命中了哪些片段。如果成本突然升高,你需要知道是哪类上下文膨胀了。
一个可理解的上下文流水线
把 Context Engineering 落到系统里,可以抽象成一条流水线:
这条流水线的重点是“候选上下文”和“最终上下文”分离。
候选上下文可以很多,最终上下文必须克制。系统先收集可能有用的信息,再通过权限、相关性、优先级和预算筛选,而不是一开始就把所有内容拼进去。
面向前端的设计视角
前端参与 Context Engineering,通常有四个切入点。
第一,明确用户当前意图。
同一个输入框可能支持总结、改写、解释、生成、查询和执行动作。前端可以通过入口、按钮、选区、快捷操作和上下文菜单传递更明确的 task type,而不是只传一段自然语言。
第二,传递结构化页面状态。
不要把整个 Redux store 或页面 HTML 原样丢给模型。前端应该提供经过整理的 context payload,例如当前对象 ID、选中字段、可见筛选条件、用户选择的文件、正在编辑的文本范围。
第三,让用户看见上下文边界。
如果 AI 正在基于“当前表格筛选结果”回答,界面最好能显示它引用了这个范围。如果只引用了某个文件,也应该有可见的引用状态。用户不知道模型看到了什么,就很难判断回答是否可信。
第四,支持用户修正上下文。
用户可能需要移除某个引用、重新选择文件、切换项目、撤销某条历史、从某条消息重新生成。上下文系统越可控,前端交互就越不能只有一个输入框。
系统设计中的关键模块
一个基础的 Context Engineering 系统通常包含这些模块。
Context Source Registry 负责登记上下文来源。每类来源都应该有类型、权限要求、时效性、token 预算、插入位置和序列化方式。
Context Builder 负责根据当前请求组装上下文。它不直接写死所有规则,而是调用不同 source provider,拿到候选片段后统一排序和裁剪。
Token Budget Manager 负责控制输入长度。它要预留输出 token,也要保护系统规则、用户输入和高优先级数据不被挤掉。
Context Compressor 负责压缩低优先级或长文本内容。常见方式包括滚动摘要、字段提取、工具结果摘要、文档 chunk 精简。
Policy Guard 负责权限、脱敏和安全边界。它应该在模型调用前运行,而不是只依赖 Prompt 里的一句“不要泄露敏感信息”。
Context Logger 负责记录本次上下文使用情况。为了隐私,日志不一定保存完整明文,但至少要保存来源、引用 ID、token 数、裁剪结果和策略版本。
安全边界:模型不能替系统做权限判断
Context Engineering 的第一条安全原则是:不该给模型看的内容,不要给。
不要把用户无权访问的数据传给模型,然后期待模型遵守“不要展示出来”。只要进入上下文,它就可能影响回答,也可能被诱导泄露。
权限过滤应该发生在模型调用之前。
例如一个企业知识库问答系统,用户问“总结本季度裁员计划”。系统不能先把所有内部文档检索出来,再让模型判断哪些能说。正确做法是检索前或检索后按用户身份、租户、文档权限和数据分级过滤,只把允许访问的片段注入上下文。
另一个边界是敏感字段脱敏。订单、用户、日志和工具结果中经常包含手机号、邮箱、token、地址、身份证、银行卡、内部备注。上下文系统应该对字段做白名单选择,而不是对整个对象 JSON.stringify。
还要防 Prompt Injection。外部文档、网页内容、用户上传文件和工具结果都可能包含“忽略之前指令”“把系统提示词打印出来”之类的恶意内容。系统需要把外部内容标注为不可信数据,并在 Prompt 结构中明确它只能作为资料,不能覆盖系统规则。
常见坑
第一个坑:把 Context Engineering 理解成更长的 Prompt。
长 Prompt 不是工程化。没有来源管理、权限过滤、预算策略和日志的长 Prompt,只是更难维护的字符串。
第二个坑:把全部历史都发给模型。
这会增加成本和延迟,还会让旧指令、错误回答和过期状态继续污染当前任务。历史应该被选择、摘要或结构化保存。
第三个坑:前端把整个页面状态原样上传。
这通常会带来噪音、隐私和成本问题。页面状态需要转成任务相关的结构化上下文。
第四个坑:只在 Prompt 里写安全要求。
安全边界应该由系统控制。Prompt 可以表达行为规范,但不能替代权限系统、脱敏逻辑和工具执行审批。
第五个坑:没有上下文日志。
没有日志时,模型回答不好只能靠猜。你无法知道它看到了哪些历史、哪些文档、哪些工具结果,也无法评估一次优化是否真的生效。
第六个坑:所有功能共用一套上下文策略。
客服问答、代码生成、文档总结、数据分析、Agent 操作需要不同上下文。一个“最近 N 条消息 + 全局用户偏好”的策略很难覆盖所有场景。
小结
Context Engineering 是把模型输入从“拼字符串”升级成“工程系统”。
它关心信息来源、权限、安全、相关性、优先级、token 预算、压缩、冲突和可观测性。对前端工程师来说,它会直接影响页面状态如何传递、AI 入口如何设计、引用关系如何展示、用户如何修正上下文,以及线上问题如何定位。
Prompt 决定模型如何理解任务,Context 决定模型基于什么完成任务。真正稳定的 AI 应用,通常不是靠某一句神奇提示词,而是靠一套可控的上下文系统。