Prompt Engineering、Harness Engineering和Context Engineering

Context Engineering vs Harness Engineering vs Prompt Engineering

这三个概念构成了 LLM 应用开发的三层技术栈,从微观到宏观、从单次交互到系统架构层层递进。


一、Prompt Engineering(提示词工程)

概念

设计、优化输入给 LLM 的文本指令,以获取最佳输出。这是最基础、最微观的层次。

核心特点

  • 作用范围:单次 LLM 调用
  • 输入输出:文本 → 文本
  • 优化目标:输出质量、准确性、格式
  • 调试方式:人工调整提示词,观察输出变化

典型技术

javascript 复制代码
// 1. 角色扮演
const prompt = `你是一位资深 Python 工程师,请审查以下代码...`;

// 2. 思维链(Chain of Thought)
const prompt = `请逐步推理:1. 首先... 2. 然后...`;

// 3. Few-shot 示例
const prompt = `示例1: ... → ...\n示例2: ... → ...\n现在处理:`;

// 4. 输出格式约束
const prompt = `以 JSON 格式输出:{"field1": "", "field2": ""}`;

局限性

  • ❌ 无状态管理(每次调用独立)
  • ❌ 无法处理超长上下文
  • ❌ 不能调用外部工具
  • ❌ 无错误恢复机制

二、Harness Engineering(脚手架工程)

概念

构建 LLM 应用的外部系统和工具链,包括工具定义、状态管理、错误处理、成本控制等。这是中间层,负责"编排"。

核心特点

  • 作用范围:整个 Agent/应用会话
  • 主要组件:工具、状态、缓存、降级、监控
  • 优化目标:系统可靠性、成本控制、用户体验
  • 调试方式:日志、链路追踪、A/B 测试

核心组件

javascript 复制代码
class Harness {
  // 1. 工具定义(让 LLM 调用外部能力)
  tools = {
    read_file: { handler: async (path) => {...} },
    execute_bash: { handler: async (cmd) => {...} },
    search_web: { handler: async (query) => {...} }
  };
  
  // 2. 状态管理(上下文窗口控制)
  manageContext() {
    if (tokenCount > 0.75 * maxTokens) {
      this.compress();  // 压缩历史
    }
  }
  
  // 3. 缓存策略(降低成本)
  setupCache() {
    // 标记稳定前缀,复用 KV Cache
    this.cachePrefix = [systemPrompt, toolDefinitions];
  }
  
  // 4. 错误处理与降级
  async callWithFallback(prompt) {
    try {
      return await callModel('opus', prompt);
    } catch {
      return await callModel('sonnet', prompt);  // 降级
    }
  }
  
  // 5. 成本控制
  estimateCost(messages) {
    return countTokens(messages) * 0.015 / 1000;
  }
}

解决的核心问题

问题 Harness 解决方案
上下文溢出 压缩、摘要、滑动窗口
工具调用失败 重试、降级、超时控制
成本失控 Token 计数、缓存、模型路由
响应不稳定 多次采样、投票机制
安全风险 工具白名单、沙箱执行

三、Context Engineering(上下文工程)

概念

设计、管理、优化 LLM 在整个任务生命周期中能看到的所有信息。这是最宏观的层次,关注"信息生态"。

核心特点

  • 作用范围:跨会话、跨 Agent、长期任务
  • 主要对象:信息选择、压缩、记忆、共享
  • 优化目标:信息密度、长期一致性、知识复用
  • 调试方式:信息检索评估、记忆召回率

上下文的层次结构

markdown 复制代码
Level 4: 长期记忆(跨会话)
         ├─ 向量数据库
         ├─ 知识图谱
         └─ 用户偏好

Level 3: 工作区上下文(项目级)
         ├─ CLAUDE.md / README
         ├─ 项目结构
         └─ 近期修改

Level 2: 会话上下文(本次对话)
         ├─ 历史消息
         ├─ 已执行操作
         └─ 中间决策

Level 1: 瞬时上下文(当前消息)
         ├─ 用户最新输入
         └─ 临时工具结果

关键技术

javascript 复制代码
// 1. 信息选择(只加载相关内容)
class ContextSelector {
  async select(query, codebase) {
    // 从 10 万行代码中检索最相关的 5 个文件
    const relevant = await vectorDB.search(query, { topK: 5 });
    // 每个文件只提取相关函数(而非全部)
    return relevant.map(f => this.extractRelevantSnippets(f));
  }
}

// 2. 信息压缩(有损但保留关键结构)
class ContextCompressor {
  compress(code, level) {
    if (level === 1) return this.extractSignatures(code);     // 只剩函数名
    if (level === 2) return this.extractSignaturesAndComments(code);
    return this.simplifyImplementation(code);                  // 保留逻辑但简化
  }
}

// 3. 长期记忆(跨会话存储)
class LongTermMemory {
  async memorize(decision) {
    await vectorDB.add(decision.embedding, decision.summary);
    await knowledgeGraph.createRelation(decision.from, decision.to);
  }
  
  async recall(question) {
    return await vectorDB.search(question);  // 语义检索
  }
}

三者的核心区别

对比表格

维度 Prompt Engineering Harness Engineering Context Engineering
作用范围 单次 LLM 调用 Agent 会话生命周期 跨会话、跨 Agent
时间尺度 毫秒级 分钟-小时级 天-周级
主要对象 文本指令 工具、状态、错误 信息选择、压缩、记忆
优化目标 输出质量 系统可靠性、成本 信息密度、长期一致性
典型问题 "怎么让模型理解意图?" "Agent卡住了怎么办?" "如何记住上周的决定?"
失败后果 回答质量差 系统崩溃、成本失控 重复工作、决策矛盾
调试方式 人工调整提示词 日志、链路追踪 检索评估、召回率
依赖关系 独立 依赖好的 Prompt 依赖 Harness 提供存储

一句话总结

  • Prompt Engineering怎么说(微观表达)
  • Harness Engineering怎么做(中观系统)
  • Context Engineering知道什么(宏观信息)

协作关系图

arduino 复制代码
用户需求
    ↓
┌─────────────────────────────────────────┐
│  Context Engineering(宏观)             │
│  "应该加载哪些历史决策?"                 │
│  "如何压缩10万行代码到2000 token?"       │
│  "如何记住上周的架构决策?"               │
└─────────────┬───────────────────────────┘
              ↓ 提供精选/压缩后的信息
┌─────────────────────────────────────────┐
│  Harness Engineering(中观)            │
│  "如何定义工具让Agent调用?"              │
│  "上下文快满了,要不要压缩?"             │
│  "工具调用失败,重试还是降级?"           │
└─────────────┬───────────────────────────┘
              ↓ 构建请求、管理状态
┌─────────────────────────────────────────┐
│  Prompt Engineering(微观)              │
│  "系统提示词怎么写?"                     │
│  "这个工具描述怎么让模型理解?"            │
│  "如何用few-shot示例引导输出格式?"       │
└─────────────┬───────────────────────────┘
              ↓ 构造最终 Prompt
           LLM 调用

实际案例对比

场景:构建一个代码审查 Agent

javascript 复制代码
// ========== 1. Prompt Engineering ==========
// 关注:如何让模型输出高质量审查意见

const reviewPrompt = `
你是一位资深代码审查专家。审查以下代码:

规则:
1. 安全性:检查 SQL 注入、XSS
2. 性能:检查 N+1 查询
3. 可维护性:检查命名、注释

输出格式:
- 🔴 严重问题
- 🟡 建议改进

代码:
${code}
`;

// ========== 2. Harness Engineering ==========
// 关注:如何让 Agent 稳定运行、控制成本

class CodeReviewHarness {
  async review(prUrl) {
    // 工具定义
    const tools = {
      get_diff: () => fetchDiff(prUrl),
      run_linter: (code) => eslint(code),
      get_file_history: (path) => gitLog(path)
    };
    
    // 状态管理:避免上下文溢出
    let context = { reviewedFiles: [], comments: [] };
    
    // 错误处理:工具调用失败时降级
    try {
      const diff = await tools.get_diff();
      for (const file of diff.files) {
        const issues = await this.reviewFile(file);
        context.comments.push(...issues);
      }
    } catch (error) {
      // 降级:只做静态分析
      return this.staticAnalysisOnly();
    }
    
    // 成本控制:预估 token 消耗
    if (this.estimateCost(context) > 0.5) {
      await this.compressHistory();
    }
    
    return context;
  }
}

// ========== 3. Context Engineering ==========
// 关注:应该加载哪些信息?如何压缩?如何记忆?

class CodeReviewContext {
  async buildContext(pr) {
    return {
      // 当前 PR 的变更
      currentDiff: await this.getDiff(pr),
      
      // 相关历史决策(从向量库检索)
      pastDecisions: await this.vectorDB.search(
        pr.description, 
        { filter: { type: 'architectural', limit: 5 } }
      ),
      
      // 项目规范(从 CLAUDE.md 加载)
      projectRules: await this.loadClaudeMd(),
      
      // 压缩策略:只保留关键信息
      compressedHistory: this.compress(pastDecisions, {
        keepSignatures: true,
        dropImplementation: true
      })
    };
  }
}

发展路径

javascript 复制代码
const learningPath = {
  beginner: "只做 Prompt Engineering",
  intermediate: "Prompt + Harness(工具、状态、错误处理)",
  advanced: "完整三层(重点是 Context Engineering)"
};

// 投入产出比
const roi = {
  promptEngineering: "低成本、高回报(适合简单任务)",
  harnessEngineering: "中成本、中回报(适合生产环境)",
  contextEngineering: "高成本、高回报(适合复杂长期任务)"
};

总结

核心区别

层次 核心问题 关键产出
Prompt 如何表达意图? 高质量的单次回复
Harness 如何构建可靠系统? 稳定运行的 Agent
Context 如何管理信息生态? 长期一致的知识体系

现代 LLM 应用的竞争壁垒

yaml 复制代码
2023 年:Prompt Engineering 是核心技能
2024 年:Harness Engineering 成为标配
2025 年:Context Engineering 是真正的护城河

原因 :当基础能力(提示词、工具调用)被模型内置后,真正区分产品优劣的是如何管理信息------知道保留什么、丢弃什么、从哪里检索、如何压缩。这也是 Claude Code、Cursor 等产品的核心竞争力所在。

相关推荐
火山引擎开发者社区19 分钟前
龙虾突然“罢工”?别慌,我们派出了“AI 医生”
人工智能
NQBJT23 分钟前
青鸾云步:基于 Cordova 的 AI 导盲机器人 APP 全栈开发实战
人工智能·app·导盲·轮足机器人·青鸾云步
深兰科技1 小时前
韩国KAIST AI半导体高管项目代表团到访深兰科技,聚焦AI算力与智能产业合作机会
人工智能·机器人·symfony·ai算力·深兰科技·韩国科学技术院·kaist
快乐on9仔1 小时前
NLP学习(一)transformers之pipeline体验
人工智能·深度学习
冬奇Lab1 小时前
Agent系列(六):记忆管理——让 Agent 记住重要的事
人工智能·agent
冬奇Lab1 小时前
一天一个开源项目(第113篇):notebooklm-py - 把 Google NotebookLM 变成可编程 API,还能接入 Claude Code
人工智能·google·开源
字节跳动开源2 小时前
Viking AI 搜索 CLI 正式发布:会说话,就能做搜索推荐
数据库·人工智能·开源
阿杰技术2 小时前
AI 编程助手落地实战:从提效到重构的全场景指南
人工智能·重构
Agent手记2 小时前
制造业生产流程自动化,Agent需要具备哪些能力?深度拆解2026工业级智能体落地范式与核心架构
大数据·人工智能·ai·架构·自动化