🧠 Context Engineering 实战教程

优化AI Agent性能的关键技术

📅 2026年7月2日 ⏱️ 阅读时间:18分钟 🎯 难度:进阶

世界上有一种技术叫Context Engineering,它就像AI的图书馆管理员。每次Agent要找资料,它都会递给你那本最对味的书。

而这,就是优化Agent性能的核心秘密。

📚 什么是Context Engineering?

🎯 核心定义

Context Engineering 是一门关于如何高效管理AI Agent上下文(Context)的技术。它包括:

  • 上下文选择:决定哪些信息应该放入Context
  • 上下文压缩:在有限Token内最大化信息密度
  • 上下文更新:动态调整Context内容
  • 上下文检索:快速找到相关历史信息
Context Quality = Relevance × Density ÷ Token_Cost

为什么Context Engineering重要?

在OpenClaw Agent中:

  • ✅ 好的Context → Agent准确理解任务 → 高质量输出
  • ❌ 差的Context → Agent困惑 → 垃圾输出
  • ⚠️ 过多的Context → Token成本飙升 → 浪费钱
  • ⚠️ 过少的Context → 信息不足 → Agent瞎猜

🔧 实战技巧1:上下文压缩

问题:Token不够用

假设你要让Agent分析一篇长文章(5000字),但GPT-4的Context Window只有8192个Token(约6000字)。

解决方案:分层压缩

# 方法1:提取关键信息
def compress_article(text):
    """压缩长文章"""
    # 步骤1:提取段落大意
    paragraphs = text.split('\n\n')
    summaries = []
    for para in paragraphs:
        summary = summarize(para)  # 使用summarization模型
        summaries.append(summary)
    
    # 步骤2:合并相关段落
    merged = merge_related(summaries)
    
    # 步骤3:生成最终摘要
    final = ' '.join(merged)
    return final

# 方法2:使用向量检索(RAG)
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')

def build_context(query, documents, max_tokens=4000):
    """构建相关上下文"""
    # 编码查询和文档
    query_embedding = model.encode(query)
    doc_embeddings = model.encode(documents)
    
    # 计算相似度
    similarities = cosine_similarity([query_embedding], doc_embeddings)[0]
    
    # 选择最相关的文档
    relevant_docs = []
    total_tokens = 0
    for idx in similarities.argsort()[::-1]:
        doc = documents[idx]
        doc_tokens = len(doc.split()) * 1.3  # 粗略估算
        if total_tokens + doc_tokens > max_tokens:
            break
        relevant_docs.append(doc)
        total_tokens += doc_tokens
    
    return '\n\n'.join(relevant_docs)
💡 周星驰式吐槽: 就像你妈让你穿秋裤,但你只穿一条。不是不穿,是要穿得刚刚好!

🔧 实战技巧2:动态上下文更新

场景:多轮对话

在OpenClaw中,Agent需要记住之前的对话内容。但随着对话变长,Context会爆炸。

解决方案:滑动窗口 + 摘要

class DynamicContextManager:
    def __init__(self, max_tokens=4000):
        self.max_tokens = max_tokens
        self.conversation = []
        self.summary = ""
    
    def add_message(self, role, content):
        """添加新消息"""
        self.conversation.append({"role": role, "content": content})
        self._optimize_context()
    
    def _optimize_context(self):
        """优化上下文"""
        # 计算当前Token数
        total_tokens = sum(len(m["content"].split()) * 1.3 for m in self.conversation)
        
        # 如果超限,进行压缩
        if total_tokens > self.max_tokens:
            # 保留最近5条消息
            recent = self.conversation[-5:]
            
            # 对前面的消息生成摘要
            older = self.conversation[:-5]
            self.summary = self._summarize(older)
            
            # 更新conversation
            self.conversation = [
                {"role": "system", "content": f"之前的对话摘要:{self.summary}"}
            ] + recent
    
    def _summarize(self, messages):
        """生成对话摘要"""
        text = "\n".join([f"{m['role']}: {m['content']}" for m in messages])
        # 调用摘要模型(省略实现)
        return summarize_text(text)
    
    def get_context(self):
        """获取优化后的上下文"""
        return self.conversation

# 使用示例
context_mgr = DynamicContextManager()
context_mgr.add_message("user", "帮我写一个Python函数计算斐波那契数列")
context_mgr.add_message("assistant", "好的,这是代码...")
context_mgr.add_message("user", "能不能优化一下性能?")
# ... 更多对话 ...

# 获取优化后的上下文
context = context_mgr.get_context()

🔧 实战技巧3:上下文检索(RAG)

场景:知识库问答

假设你的Agent需要回答关于OpenClaw的问题,但OpenClaw文档有几百页。

解决方案:向量数据库 + 语义检索

import chromadb
from sentence_transformers import SentenceTransformer

class RAGContextProvider:
    def __init__(self, docs_dir):
        self.model = SentenceTransformer('all-MiniLM-L6-v2')
        self.client = chromadb.Client()
        self.collection = self.client.create_collection("openclaw-docs")
        
        # 加载文档
        self._load_documents(docs_dir)
    
    def _load_documents(self, docs_dir):
        """加载并索引文档"""
        docs = []
        for file in os.listdir(docs_dir):
            with open(os.path.join(docs_dir, file), 'r') as f:
                text = f.read()
                # 分块
                chunks = self._chunk_text(text, chunk_size=500)
                docs.extend(chunks)
        
        # 生成嵌入并存储
        embeddings = self.model.encode(docs)
        self.collection.add(
            embeddings=embeddings.tolist(),
            documents=docs,
            ids=[f"doc_{i}" for i in range(len(docs))]
        )
    
    def _chunk_text(self, text, chunk_size=500):
        """将文本分块"""
        words = text.split()
        chunks = []
        for i in range(0, len(words), chunk_size):
            chunk = ' '.join(words[i:i+chunk_size])
            chunks.append(chunk)
        return chunks
    
    def get_relevant_context(self, query, n_results=3):
        """获取相关上下文"""
        query_embedding = self.model.encode(query).tolist()
        results = self.collection.query(
            query_embeddings=[query_embedding],
            n_results=n_results
        )
        return results['documents'][0]

# 使用示例
rag = RAGContextProvider("/path/to/openclaw/docs")

# Agent处理问题时
query = "如何在OpenClaw中安装Skill?"
context = rag.get_relevant_context(query)
# context包含最相关的文档片段

# 将context放入Agent的prompt
prompt = f"""
根据以下上下文回答问题:

{context}

问题:{query}
"""
# 调用LLM...

📝 实际效果对比

没有RAG:

Q: "如何在OpenClaw中安装Skill?"
A: "抱歉,我不知道。" (因为不在Context中)

有RAG:

Q: "如何在OpenClaw中安装Skill?"
A: "根据文档,你可以通过以下方式安装Skill:
1. 使用CLI: openclaw skill install <skill-name>
2. 从ClawHub网站下载后安装..." (因为检索到了相关文档)

📊 性能优化最佳实践

1. 根据任务类型调整Context

任务类型 推荐Context策略
代码生成 提供完整的需求描述 + 相关代码示例
文档问答 使用RAG检索最相关的文档片段
数据分析 提供数据样本 + 分析目标 + 类似案例
创意写作 提供风格示例 + 主题要求 + 限制条件

2. 监控Token使用

# OpenClaw中监控Token使用
import tiktoken

def count_tokens(text, model="gpt-4"):
    """计算Token数"""
    enc = tiktoken.encoding_for_model(model)
    return len(enc.encode(text))

# 在Agent执行前后统计
class TokenMonitor:
    def __init__(self):
        self.start_tokens = 0
        self.end_tokens = 0
    
    def start(self, context):
        self.start_tokens = count_tokens(str(context))
    
    def end(self, output):
        self.end_tokens = count_tokens(str(output))
    
    def report(self):
        print(f"Context Token数: {self.start_tokens}")
        print(f"Output Token数: {self.end_tokens}")
        print(f"Total Token数: {self.start_tokens + self.end_tokens}")
        print(f"预估成本: ${ (self.start_tokens + self.end_tokens) * 0.00003:.4f}")

# 使用
monitor = TokenMonitor()
monitor.start(agent.context)
output = agent.run()
monitor.end(output)
monitor.report()