Context Engineering vs Harness Engineering vs Prompt Engineering
這三個概念構成了 LLM 應用開發的三層技術棧,從微觀到宏觀、從單次交互到系統架構層層遞進。
一、Prompt Engineering(提示詞工程)
概念
設計、優化輸入給 LLM 的文本指令,以獲取最佳輸出。這是最基礎、最微觀的層次。
核心特點
- 作用範圍:單次 LLM 調用
- 輸入輸出:文本 → 文本
- 優化目標:輸出質量、準確性、格式
- 調試方式:人工調整提示詞,觀察輸出變化
典型技術
// 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 測試
核心組件
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、長期任務
- 主要對象:信息選擇、壓縮、記憶、共享
- 優化目標:信息密度、長期一致性、知識複用
- 調試方式:信息檢索評估、記憶召回率
上下文的層次結構
Level 4: 長期記憶(跨會話)
├─ 向量數據庫
├─ 知識圖譜
└─ 用戶偏好
Level 3: 工作區上下文(項目級)
├─ CLAUDE.md / README
├─ 項目結構
└─ 近期修改
Level 2: 會話上下文(本次對話)
├─ 歷史消息
├─ 已執行操作
└─ 中間決策
Level 1: 瞬時上下文(當前消息)
├─ 用戶最新輸入
└─ 臨時工具結果
關鍵技術
// 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:知道什麼(宏觀信息)
協作關係圖
用戶需求
↓
┌─────────────────────────────────────────┐
│ Context Engineering(宏觀) │
│ "應該加載哪些歷史決策?" │
│ "如何壓縮10萬行代碼到2000 token?" │
│ "如何記住上週的架構決策?" │
└─────────────┬───────────────────────────┘
↓ 提供精選/壓縮後的信息
┌─────────────────────────────────────────┐
│ Harness Engineering(中觀) │
│ "如何定義工具讓Agent調用?" │
│ "上下文快滿了,要不要壓縮?" │
│ "工具調用失敗,重試還是降級?" │
└─────────────┬───────────────────────────┘
↓ 構建請求、管理狀態
┌─────────────────────────────────────────┐
│ Prompt Engineering(微觀) │
│ "系統提示詞怎麼寫?" │
│ "這個工具描述怎麼讓模型理解?" │
│ "如何用few-shot示例引導輸出格式?" │
└─────────────┬───────────────────────────┘
↓ 構造最終 Prompt
LLM 調用
實際案例對比
場景:構建一個代碼審查 Agent
// ========== 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
})
};
}
}
發展路徑
const learningPath = {
beginner: "只做 Prompt Engineering",
intermediate: "Prompt + Harness(工具、狀態、錯誤處理)",
advanced: "完整三層(重點是 Context Engineering)"
};
// 投入產出比
const roi = {
promptEngineering: "低成本、高回報(適合簡單任務)",
harnessEngineering: "中成本、中回報(適合生產環境)",
contextEngineering: "高成本、高回報(適合複雜長期任務)"
};
總結
核心區別
| 層次 | 核心問題 | 關鍵產出 |
|---|---|---|
| Prompt | 如何表達意圖? | 高質量的單次回覆 |
| Harness | 如何構建可靠系統? | 穩定運行的 Agent |
| Context | 如何管理信息生態? | 長期一致的知識體系 |
現代 LLM 應用的競爭壁壘
2023 年:Prompt Engineering 是核心技能
2024 年:Harness Engineering 成為標配
2025 年:Context Engineering 是真正的護城河
原因:當基礎能力(提示詞、工具調用)被模型內置後,真正區分產品優劣的是如何管理信息——知道保留什麼、丟棄什麼、從哪裡檢索、如何壓縮。這也是 Claude Code、Cursor 等產品的核心競爭力所在。










