超越Prompt Engineering的新范式:系统化构建LLM最优输入上下文
Context Engineering(上下文工程)是Prompt Engineering的进化形态。它不只是写好一句prompt,而是系统化地设计、组装、优化输入给LLM的完整上下文——包括系统提示、工具描述、历史记忆、检索结果、结构化数据等——让模型在有限的上下文窗口内获得最丰富的决策信息。
2025年底,随着AI Agent系统的复杂度飙升,开发者们发现:单靠写好一句prompt已经远远不够了。一个成熟的Agent系统需要在每次调用LLM时,动态组装包含以下内容的上下文:
Context Engineering就是研究如何高效地选择、组织、压缩、优先级排序这些信息,使其在有限的上下文窗口(如128K、200K tokens)内最大化LLM的推理质量。
一个现代AI Agent可能同时拥有20+个工具、多层记忆系统、实时RAG检索。如何在每次LLM调用时塞入最相关的信息,而不是把所有东西一股脑扔进去,成为关键挑战。
虽然窗口已经扩展到200K+ tokens,但每多塞一个token都意味着:
LLM的推理质量高度依赖输入上下文的质量。垃圾进,垃圾出。精心策划的上下文可以让小模型超越大模型的表现。
| 层级 | 内容 | 更新频率 | Token占比 |
|---|---|---|---|
| 静态层 | System Prompt、工具Schema | 会话级 | 15-25% |
| 动态层 | RAG结果、工具返回值 | 每轮调用 | 30-50% |
| 历史层 | 对话历史、记忆 | 滑动窗口 | 20-40% |
| 元数据层 | 时间、用户画像、任务状态 | 准实时 | 5-10% |
当上下文空间不足时,需要决定什么信息优先保留:
OpenClaw在架构层面深度践行了Context Engineering理念:
OpenClaw的SOUL.md文件定义了Agent的核心人格和行为规则,作为每次调用的System Prompt基础层。这确保了Agent在所有交互中保持一致的行为模式。
当Agent匹配到特定Skill时,SKILL.md的内容被动态注入上下文。这是一种按需加载的上下文工程策略——不把所有技能说明都塞进去,只在需要时加载相关技能。
OpenClaw的memory-core Skill实现了分层记忆管理:
# OpenClaw每次调用LLM时的上下文组装逻辑 context_layers: # 第1层:静态人格(始终加载) soul: source: "SOUL.md" priority: "critical" max_tokens: 2000 # 第2层:技能说明(按需加载) skills: source: "SKILL.md" priority: "high" strategy: "match_and_load" max_tokens: 3000 # 第3层:工具Schema(动态筛选) tools: source: "tool_registry" priority: "high" strategy: "relevance_filter" max_tokens: 4000 # 第4层:记忆上下文 memory: short_term: "conversation_history" long_term: "MEMORY.md + vector_search" strategy: "summarize_old + keep_recent" max_tokens: 8000 # 第5层:RAG检索结果 retrieval: source: "web_search + doc_fetch" priority: "medium" strategy: "top_k_relevance" max_tokens: 6000 # 总Token预算:128K窗口中使用约25K # 保留足够空间给模型推理和输出
def compress_context(messages, max_tokens=8000): """ OpenClaw风格的上下文压缩策略 保留最近N轮完整对话,老对话压缩为摘要 """ # 1. 始终保留最近3轮完整对话 recent = messages[-6:] # 3轮 = 6条消息 # 2. 老对话压缩为摘要 older = messages[:-6] if older: summary = summarize_messages(older) # 摘要格式: "[早期对话摘要] 用户讨论了X话题..." context = [summary] + recent else: context = recent # 3. 如果还超长,按重要性截断 if count_tokens(context) > max_tokens: context = truncate_by_importance(context, max_tokens) return context