对比 Prompt 工程、上下文工程的主要区别与联系
一、Harness 工程(Harness Engineering)概述
1.1 什么是 Harness 工程?
Harness Engineering (Harness 工程)是一种系统化的 AI 应用开发方法论,核心目标是构建可测试、可评估、可迭代、可部署 的 LLM(大语言模型)应用流水线。它强调将 LLM 视为一个可编程的组件,通过严格的工程化手段(如版本控制、A/B 测试、监控、自动化评估)来管理其不确定性。
"Harness" 一词原意为"马具",引申为约束与引导------即通过工程框架来"驾驭" LLM 的强大但不可预测的能力。
1.2 核心设计原则
| 原则 | 说明 |
|---|---|
| 可观测性(Observability) | 对模型的输入、输出、中间状态进行全链路追踪和日志记录 |
| 可评估性(Evaluability) | 建立明确的评估指标(Accuracy、Latency、Cost、Safety)和自动化测试集 |
| 可配置性(Configurability) | 将 Prompt、模型参数、业务逻辑解耦,支持动态切换和灰度发布 |
| 可回滚性(Rollback) | 支持模型版本、Prompt 版本、数据版本的原子化回滚 |
| 模块化(Modularity) | 将复杂任务拆分为可复用的子模块(Chain、Agent、Tool) |
1.3 典型架构组件
+-------------------------------------------------------------+
| Harness 工程架构全景 |
+-------------------------------------------------------------+
| 应用层 (Application) |
| +-- Chatbot / Copilot / RAG System / Agent Swarm |
+-------------------------------------------------------------+
| 编排层 (Orchestration) |
| +-- LangChain / LlamaIndex / Semantic Kernel |
| +-- 工作流引擎 (Workflow Engine) |
| +-- 路由逻辑 (Routing Logic) |
+-------------------------------------------------------------+
| 模型层 (Model Layer) |
| +-- 模型网关 (Model Gateway) - 统一调用多厂商 API |
| +-- 负载均衡 (Load Balancer) |
| +-- 降级策略 (Fallback Strategy) |
+-------------------------------------------------------------+
| 数据层 (Data Layer) |
| +-- 向量数据库 (Vector DB) |
| +-- 提示词仓库 (Prompt Registry) |
| +-- 评估数据集 (Evaluation Dataset) |
+-------------------------------------------------------------+
| 评估层 (Evaluation) |
| +-- 离线评估 (Offline Eval) - 单元测试、回归测试 |
| +-- 在线评估 (Online Eval) - A/B Test、Shadow Traffic |
| +-- 人工评估 (Human Eval) - RLHF、标注平台 |
+-------------------------------------------------------------+
| 监控层 (Monitoring) |
| +-- 性能监控 (Latency/Throughput) |
| +-- 质量监控 (Output Quality Drift) |
| +-- 成本监控 (Token Usage / API Cost) |
+-------------------------------------------------------------+
1.4 关键设计规则
- 输入输出契约化:定义严格的输入 Schema(Pydantic)和输出 Schema,拒绝模糊接口
- 防御性编程:对模型输出进行后置校验(JSON Schema Validation、内容安全过滤)
- 超时与重试:设置合理的 Timeout 和 Exponential Backoff 策略
- 成本预算控制:设置 Token 上限和单次调用成本阈值
- 渐进式发布:通过 Feature Flag 控制新 Prompt/模型的灰度范围
- 数据飞轮:将生产环境的用户反馈自动回流到评估数据集和训练数据
二、Prompt 工程(Prompt Engineering)
2.1 定义与定位
Prompt 工程 是通过设计和优化输入提示词(Prompt),来引导 LLM 生成期望输出的技术。它是最前端、最直接的交互层优化手段。
2.2 核心技术与模式
| 技术 | 说明 | 示例 |
|---|---|---|
| Zero-shot | 直接描述任务,不给示例 | "将以下中文翻译成英文:..." |
| Few-shot | 提供少量输入-输出示例 | "示例1:... -> ... 示例2:... -> ... 现在:..." |
| Chain-of-Thought (CoT) | 引导模型逐步推理 | "Let's think step by step..." |
| ReAct | 推理与行动交替 | "Thought: ... Action: ... Observation: ..." |
| System Prompt 设计 | 定义角色、约束、输出格式 | "你是一位专业的法律顾问,请用 JSON 格式回答..." |
| Prompt 模板化 | 使用 Jinja2/f-string 动态填充变量 | "请总结以下文章:{``{ article }}" |
2.3 局限性
- 脆弱性:微小的 Prompt 改动可能导致输出大幅波动
- 不可扩展:难以应对复杂多步骤任务
- 难以评估:缺乏系统化的效果衡量标准
- 知识边界:无法突破模型预训练知识的限制
三、上下文工程(Context Engineering)
3.1 定义与定位
上下文工程 是 Prompt 工程的超集和延伸 ,不仅关注单次输入的 Prompt 设计,更关注如何构建、管理、检索和注入上下文信息,以扩展模型的有效记忆和知识边界。
3.2 核心关注点
| 维度 | 说明 | 关键技术 |
|---|---|---|
| 上下文构建 | 将外部知识转化为模型可理解的格式 | RAG(检索增强生成)、文档分块、Embedding |
| 上下文管理 | 处理长对话历史的记忆问题 | 滑动窗口、摘要压缩、Token 预算管理 |
| 上下文检索 | 从海量数据中召回相关信息 | 向量检索(Vector Search)、混合检索(BM25 + Dense) |
| 上下文注入 | 将检索到的信息优雅地插入 Prompt | 上下文填充策略(Prefix/Suffix/Interleaved) |
| 上下文评估 | 衡量上下文对最终输出的贡献度 | 上下文相关性(Context Relevance)、召回率 |
3.3 RAG 架构示例
用户查询 -> Query理解/改写 -> 向量检索 -> 重排序(Rerank) -> 上下文组装 -> Prompt构建 -> LLM生成 -> 输出后处理
^ ^
+------------ 知识库/向量数据库 ----------------+
四、三者对比:Harness vs Prompt vs Context
4.1 核心区别
| 维度 | Prompt 工程 | 上下文工程 | Harness 工程 |
|---|---|---|---|
| 关注层级 | 单点输入优化 | 信息供给与记忆管理 | 全生命周期系统构建 |
| 时间维度 | 单次交互 | 多轮对话/会话 | 持续迭代与演进 |
| 核心目标 | 让模型"听懂"指令 | 让模型"记得"更多信息 | 让系统"可靠"运行 |
| 技术栈 | Prompt 模板、Few-shot 示例 | RAG、向量数据库、Embedding | CI/CD、评估框架、监控体系 |
| 评估方式 | 人工抽查、主观判断 | 检索准确率、上下文相关性 | 自动化测试、A/B Test、指标仪表盘 |
| 风险管控 | 几乎无 | 检索失败兜底 | 全链路熔断、降级、审计 |
| 团队协作 | 个人技巧 | 算法+工程协作 | 跨职能团队(PM/算法/工程/运营) |
| 适用场景 | 原型验证、简单任务 | 知识密集型应用 | 生产级 AI 产品 |
4.2 核心联系
+-----------------+
| Harness 工程 | <- 顶层框架:提供基础设施与治理
| (系统与流程) |
+--------+--------+
| 包含与管理
+----------------+----------------+
| | |
v v v
+--------------+ +--------------+ +--------------+
| 上下文工程 | | Prompt 工程 | | 模型工程 |
| (信息供给层) | | (指令交互层) | | (底座能力层) |
+--------------+ +--------------+ +--------------+
^ ^
+----------------+
上下文工程为 Prompt 提供"弹药"
Prompt 工程为上下文提供"表达方式"
联系详解:
- 包含关系:Harness 工程包含 Prompt 工程和上下文工程,将其作为系统内的可配置模块进行管理
- 依赖关系 :
- 上下文工程是 Prompt 工程的前置条件------没有高质量的上下文,再优秀的 Prompt 也无法弥补知识缺口
- Prompt 工程是上下文工程的表达方式------再好的检索结果也需要通过精心设计的 Prompt 来引导模型利用
- 互补关系 :
- Prompt 工程解决"怎么说"的问题
- 上下文工程解决"说什么"的问题
- Harness 工程解决"如何持续说好"的问题
4.3 演进路径
阶段1: Prompt 工程(单点优化)
v 遇到知识边界和记忆限制
阶段2: 上下文工程(信息增强)
v 遇到可靠性、可维护性、团队协作问题
阶段3: Harness 工程(系统构建)
v 形成数据飞轮,持续迭代优化
阶段4: AI 原生应用(产品化)
五、实践建议:如何选择与结合
5.1 决策矩阵
| 场景特征 | 推荐重点 | 说明 |
|---|---|---|
| 原型/MVP 阶段 | Prompt 工程 | 快速验证可行性,成本最低 |
| 需要外部知识 | 上下文工程 + Prompt 工程 | RAG 是性价比最高的知识增强方案 |
| 多人协作/生产环境 | Harness 工程 | 必须建立评估体系和版本管理 |
| 高 stakes 场景(医疗/金融) | 全栈 Harness | 需要严格的审计、安全、合规 |
5.2 最佳实践组合
# 伪代码示例:三者的协同工作
class AIApplication:
def __init__(self):
# Harness 层:配置管理与版本控制
self.config = ConfigManager(version="v2.3.1")
self.evaluator = Evaluator(metrics=["accuracy", "latency", "cost"])
self.monitor = Monitor()
# 上下文层:检索与记忆
self.retriever = VectorRetriever(
db=self.config.vector_db,
top_k=5,
reranker=self.config.reranker
)
self.memory = ConversationMemory(max_tokens=2000)
# Prompt 层:模板与策略
self.prompt_template = PromptTemplate(
system_msg=self.config.system_prompt,
few_shot_examples=self.config.examples
)
@trace # Harness 层:全链路追踪
@evaluate # Harness 层:自动评估
def generate(self, user_query: str) -> str:
# 1. 上下文工程:检索相关知识
context = self.retriever.search(user_query)
history = self.memory.get_recent()
# 2. Prompt 工程:构建最终 Prompt
prompt = self.prompt_template.render(
context=context,
history=history,
query=user_query
)
# 3. Harness 层:调用模型并监控
with self.monitor.track():
response = self.config.llm.generate(
prompt,
max_tokens=self.config.max_tokens,
temperature=self.config.temperature
)
# 4. Harness 层:后置校验与反馈
validated = self.output_validator.check(response)
self.memory.add_turn(user_query, validated)
return validated
六、总结
| Prompt 工程 | 上下文工程 | Harness 工程 | |
|---|---|---|---|
| 本质 | 沟通艺术 | 信息管理 | 系统工程 |
| 核心问题 | 如何让模型理解意图? | 如何让模型掌握更多知识? | 如何让 AI 应用稳定可靠? |
| 关键产出 | 高质量 Prompt 模板 | 高效检索与记忆机制 | 可迭代的 AI 产品流水线 |
| 成功标志 | 输出质量提升 | 知识覆盖度提升 | 业务指标持续优化 |
最终建议 :Prompt 工程是"术",上下文工程是"法",Harness 工程是"道"。三者并非替代关系,而是由点及面、由浅入深的递进关系。在生产环境中,应以 Harness 工程为框架,将 Prompt 工程和上下文工程作为其核心组件,通过数据驱动的方式持续优化,才能构建出真正可靠、可扩展的 AI 应用。
七、Harness 工程深度拆解
7.1 评估体系(Evaluation Framework)
评估是 Harness 工程的核心驱动力。没有评估,优化就是盲目的。
7.1.1 评估维度矩阵
| 维度 | 指标 | 测量方式 | 工具示例 |
|---|---|---|---|
| 正确性 | Accuracy、F1、BLEU、ROUGE | 与标准答案对比 | deepeval、ragas |
| 相关性 | Context Relevance、Answer Relevance | LLM-as-Judge | trulens、arize |
| 忠实度 | Faithfulness、Hallucination Rate | 事实一致性检查 | guardrails-ai |
| 安全性 | Toxicity、PII 泄露、Prompt 注入抵抗 | 分类器/规则引擎 | Lakera、Prompt Armor |
| 性能 | Latency (P50/P95/P99)、Throughput | 压测工具 | Locust、k6 |
| 成本 | Token 消耗、API 调用费用 | 计费接口 | OpenAI Usage、自定义埋点 |
| 用户体验 | 满意度评分、任务完成率 | 用户反馈收集 | 内置评分组件 |
7.1.2 离线评估 vs 在线评估
离线评估 (Offline Eval) 在线评估 (Online Eval)
+-- 基于固定测试集 +-- A/B Test
+-- 回归测试(防止性能退化) +-- Shadow Traffic(影子流量)
+-- 单元测试(单个组件测试) +-- Canary Release(金丝雀发布)
+-- 成本:低,可频繁运行 +-- 成本:高,需谨慎设计
+-- 局限:无法覆盖真实分布 +-- 优势:反映真实用户场景
7.1.3 LLM-as-Judge 模式
# 使用更强的模型作为评判者
from deepeval import evaluate
from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCase
metric = GEval(
name="Coherence",
criteria="评估回答是否逻辑连贯、条理清晰",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT]
)
test_case = LLMTestCase(
input="解释量子纠缠",
actual_output="量子纠缠是量子力学中的一种现象..."
)
metric.measure(test_case)
print(metric.score) # 0-1 分数
print(metric.reason) # 评判理由
7.2 版本管理与 CI/CD
7.2.1 需要版本化的对象
| 对象 | 版本管理工具 | 说明 |
|---|---|---|
| Prompt 模板 | Git + Prompt Registry (如 LangSmith) | 每次修改需记录变更原因 |
| 模型配置 | Git + 配置中心 (如 Consul) | 温度、Top-p、Max Tokens 等 |
| 评估数据集 | DVC / Git LFS | 数据版本与代码版本联动 |
| 向量索引 | 专用版本系统 | Embedding 模型变更需重建索引 |
| 业务逻辑代码 | Git | 传统软件工程实践 |
7.2.2 AI 应用的 CI/CD 流水线
# .github/workflows/ai-ci.yml (概念示例)
name: AI Application CI/CD
on:
push:
paths:
- 'prompts/**'
- 'src/**'
- 'eval/**'
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Unit Tests
run: pytest tests/unit/
- name: Run Prompt Regression Tests
run: python -m eval.prompt_regression
# 对比新版本与基线的评估指标差异
- name: Run Safety Checks
run: python -m eval.safety_scan
# 检查 Prompt 注入、越狱攻击抵抗力
- name: Cost Benchmark
run: python -m eval.cost_benchmark
# 确保 Token 消耗在预算范围内
deploy-staging:
needs: test
steps:
- name: Deploy to Staging
run: ./scripts/deploy.sh staging
- name: Shadow Traffic Test
run: python -m eval.shadow_traffic --duration=30m
deploy-production:
needs: deploy-staging
steps:
- name: Canary Release (5%)
run: ./scripts/deploy.sh production --canary=5
- name: Monitor Metrics
run: python -m eval.canary_monitor --threshold=0.01
# 如果错误率上升超过 1%,自动回滚
7.3 监控与可观测性
7.3.1 关键监控指标
# 监控指标定义示例
MONITORING_METRICS = {
# 性能指标
"request_latency": {"type": "histogram", "buckets": [0.1, 0.5, 1, 2, 5, 10]},
"token_usage": {"type": "counter", "labels": ["model", "endpoint"]},
"queue_depth": {"type": "gauge"},
# 质量指标
"output_length": {"type": "histogram"},
"json_valid_rate": {"type": "gauge"}, # 结构化输出成功率
"retry_count": {"type": "counter"},
# 业务指标
"user_satisfaction": {"type": "gauge", "source": "explicit_feedback"},
"task_completion_rate": {"type": "gauge"},
"conversation_turns": {"type": "histogram"},
# 安全指标
"toxicity_flagged": {"type": "counter"},
"pii_detected": {"type": "counter"},
"prompt_injection_attempts": {"type": "counter"},
}
7.3.2 追踪链路设计
Trace ID: ai-req-7f3a9b2c
+-- Span: user_input_received
| +-- tags: {user_id, session_id, query_length}
+-- Span: query_rewrite
| +-- tags: {model: gpt-4o-mini, latency: 0.3s, tokens: 150}
+-- Span: vector_search
| +-- tags: {index_version: v2.1, recall_top5: 0.82, latency: 0.05s}
+-- Span: prompt_assembly
| +-- tags: {prompt_version: v3.2.1, context_chunks: 5}
+-- Span: llm_generation
| +-- tags: {model: gpt-4o, latency: 2.1s, input_tokens: 2048, output_tokens: 512}
+-- Span: output_validation
| +-- tags: {json_valid: true, safety_passed: true}
+-- Span: response_delivered
+-- tags: {total_latency: 2.6s, user_feedback: thumbs_up}
7.4 安全与合规
7.4.1 多层防御体系
+---------------------------------------------+
| 第1层:输入过滤 (Input Sanitization) |
| +-- Prompt 注入检测(正则/分类器) |
| +-- 越狱攻击模式识别 |
| +-- 敏感信息脱敏(PII 检测) |
+---------------------------------------------+
| 第2层:模型层安全 (Model Safety) |
| +-- 使用带安全对齐的模型(如 GPT-4) |
| +-- 系统 Prompt 中嵌入安全约束 |
| +-- 输出格式强制(JSON Schema 约束) |
+---------------------------------------------+
| 第3层:输出过滤 (Output Filtering) |
| +-- 内容安全分类(Toxicity/偏见) |
| +-- 事实一致性校验(针对 RAG 场景) |
| +-- 敏感信息二次过滤 |
+---------------------------------------------+
| 第4层:审计与合规 (Audit & Compliance) |
| +-- 全量日志留存(满足法规要求) |
| +-- 人工审核队列(高风险输出) |
| +-- 用户申诉与反馈机制 |
+---------------------------------------------+
八、Prompt 工程进阶技术
8.1 结构化 Prompt 设计模式
# 结构化 Prompt 模板(XML/JSON 风格)
## 角色定义
<role>
你是一位拥有10年经验的资深 Python 开发工程师,擅长代码审查和性能优化。
</role>
## 任务描述
<task>
请审查以下代码,找出潜在的性能瓶颈和安全漏洞。
</task>
## 输入数据
<code>
{{ user_code }}
</code>
## 输出格式要求
<output_format>
请以 JSON 格式返回,包含以下字段:
- issues: 问题列表(每个问题包含 severity、line、description、fix_suggestion)
- overall_score: 综合评分(1-10)
- summary: 总体评价
</output_format>
## 约束条件
<constraints>
- 只关注性能和安全问题,忽略代码风格
- 如果代码没有明显问题,请明确说明"未发现严重问题"
- 每个问题必须提供具体的修复建议
</constraints>
## 示例
<example>
输入:...
输出:{"issues": [...], "overall_score": 7, "summary": "..."}
</example>
8.2 动态 Few-shot 选择
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
class DynamicFewShotSelector:
"""根据用户查询动态选择最相关的 Few-shot 示例"""
def __init__(self, examples, embedding_model):
self.examples = examples
self.embeddings = embedding_model.encode([ex["query"] for ex in examples])
def select(self, user_query, k=3):
query_emb = self.embedding_model.encode([user_query])
similarities = cosine_similarity(query_emb, self.embeddings)[0]
top_indices = np.argsort(similarities)[-k:][::-1]
return [self.examples[i] for i in top_indices]
# 使用示例
selector = DynamicFewShotSelector(examples, embedding_model)
relevant_examples = selector.select(user_query, k=3)
prompt = build_prompt_with_examples(relevant_examples, user_query)
8.3 Prompt 压缩技术
| 技术 | 原理 | 适用场景 |
|---|---|---|
| 摘要压缩 | 用 LLM 将长上下文压缩为摘要 | 长文档对话 |
| 选择性保留 | 只保留与当前查询最相关的片段 | RAG 场景 |
| Token 预算分配 | 按优先级分配 Token(系统 > 上下文 > 历史 > 查询) | 通用场景 |
| 语义压缩 | 将语义相近的句子合并 | 高度冗余的上下文 |
def allocate_token_budget(total_budget, priorities):
"""
优先级分配 Token 预算
priorities: {"system": 0.3, "context": 0.4, "history": 0.2, "query": 0.1}
"""
allocation = {}
for key, ratio in priorities.items():
allocation[key] = int(total_budget * ratio)
return allocation
九、上下文工程深度技术
9.1 高级 RAG 架构模式
9.1.1 从基础 RAG 到高级 RAG
基础 RAG: 查询 -> 向量检索 -> 直接生成
v
高级 RAG:
+-- 查询重写 (Query Rewriting)
| +-- HyDE: 生成假设答案再检索
| +-- 多查询扩展: 一个查询拆分为多个子查询
+-- 检索增强
| +-- 混合检索: Dense + Sparse (BM25)
| +-- 重排序 (Rerank): Cross-Encoder 精排
| +-- 元数据过滤: 先过滤再检索
+-- 上下文后处理
| +-- 去重与合并
| +-- 时间排序/相关性排序
| +-- 上下文压缩
+-- 生成增强
+-- 引用溯源 (Citation)
+-- 多文档融合生成
9.1.2 Agentic RAG
class AgenticRAG:
"""具备决策能力的 RAG 系统"""
def __init__(self):
self.retriever = Retriever()
self.generator = Generator()
self.critic = Critic() # 评估检索质量
def run(self, query, max_iterations=3):
context = []
for i in range(max_iterations):
# 检索
new_docs = self.retriever.search(query, exclude=context)
context.extend(new_docs)
# 生成草稿
draft = self.generator.generate(query, context)
# 自我评估
assessment = self.critic.evaluate(query, draft, context)
if assessment.is_sufficient:
return draft
elif assessment.needs_more_context:
query = assessment.refined_query # 改写查询继续检索
else:
return draft # 无法继续优化
return draft
9.2 长上下文管理策略
| 策略 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 滑动窗口 | 保留最近 N 轮对话 | 简单高效 | 丢失早期信息 |
| 摘要记忆 | 定期将历史摘要压缩 | 保留长期脉络 | 细节丢失 |
| 层次化记忆 | 短期记忆 + 长期记忆 + 实体记忆 | 信息分层管理 | 实现复杂 |
| 向量记忆 | 所有历史转为向量,按需检索 | 理论上无限记忆 | 检索质量依赖 Embedding |
class HierarchicalMemory:
"""层次化记忆系统"""
def __init__(self):
self.short_term = [] # 最近 N 轮(完整文本)
self.long_term = [] # 压缩后的摘要
self.entity_memory = {} # 关键实体信息(如用户偏好)
def add(self, user_msg, assistant_msg):
self.short_term.append((user_msg, assistant_msg))
# 当短期记忆溢出时,生成摘要转入长期记忆
if len(self.short_term) > 10:
summary = self.summarize(self.short_term)
self.long_term.append(summary)
self.short_term = []
# 提取实体更新
entities = self.extract_entities(summary)
self.entity_memory.update(entities)
def get_context(self, query, max_tokens=4000):
# 优先使用短期记忆
context = self.format_turns(self.short_term)
# 如果还有空间,加入相关的长期记忆
remaining = max_tokens - self.estimate_tokens(context)
if remaining > 500:
relevant_summaries = self.retrieve_relevant(self.long_term, query)
context = self.format_summaries(relevant_summaries) + context
# 如果还有空间,加入实体记忆
remaining = max_tokens - self.estimate_tokens(context)
if remaining > 200:
context = self.format_entities(self.entity_memory) + context
return context
9.3 上下文注入的最佳实践
# 最佳实践:清晰的上下文边界标记
PROMPT_TEMPLATE = """基于以下参考资料回答问题。如果参考资料中没有相关信息,请明确说明"根据现有资料无法回答"。
## 参考资料
{% for doc in context_docs %}
[文档 {{ loop.index }}] 来源: {{ doc.source }}
{{ doc.content }}
{% endfor %}
## 历史对话
{% for turn in history %}
用户: {{ turn.user }}
助手: {{ turn.assistant }}
{% endfor %}
## 当前问题
用户: {{ query }}
## 回答要求
- 优先使用参考资料中的信息
- 如涉及多个文档,请分别引用 [文档 X]
- 保持简洁,不超过 300 字
助手:"""
十、三者协同的完整案例
10.1 智能客服系统架构
+--------------------------------------------------------------+
| 智能客服系统 (Smart CS) |
+--------------------------------------------------------------+
| |
| +-------------+ +-------------+ +-------------+ |
| | 用户输入 |--->| 意图识别 |--->| 路由决策 | |
| | | | (分类模型) | | | |
| +-------------+ +-------------+ +------+------+ |
| | |
| +--------------------+---------+ |
| | | | |
| +----------+ +----------+ +----+|
| | FAQ 问答 | | 复杂问题 | |转人工||
| | (RAG) | | (Agent) | | ||
| +----+-----+ +----+-----+ +----+|
| | | |
| +----------------------+| +----------------+| |
| | 上下文工程层 || | 上下文工程层 || |
| | + 知识库向量检索 || | + 多工具调用 || |
| | + 历史对话检索 || | + 外部 API 查询 || |
| | + 用户画像注入 || | + 数据库查询 || |
| +----------------------+| +----------------+| |
| | | |
| +----------------------+| +----------------+| |
| | Prompt 工程层 || | Prompt 工程层 || |
| | + FAQ 专用模板 || | + ReAct 模板 || |
| | + Few-shot 示例 || | + 工具描述注入 || |
| | + 输出格式约束 || | + 推理链引导 || |
| +----------------------+| +----------------+| |
| | | |
| +----------------------+| +----------------+| |
| | Harness 工程层 || | Harness 工程层 || |
| | + 响应时间 < 2s || | + 多步超时控制 || |
| | + 答案置信度阈值 || | + 工具调用审计 || |
| | + 不满意自动升级 || | + 异常回退兜底 || |
| | + A/B 测试不同模板 || | + 成本预算控制 || |
| +----------------------+| +----------------+| |
| | | |
| v v |
| +--------------------------------+ |
| | 统一输出与监控层 | |
| | + 安全过滤 + 格式校验 + 日志追踪 | |
| +--------------------------------+ |
| |
+--------------------------------------------------------------+
10.2 代码实现骨架
"""
智能客服系统 - 三工程协同示例
"""
from dataclasses import dataclass
from typing import List, Dict, Optional, Callable
from enum import Enum
import time
import json
# ==================== Harness 工程层 ====================
class MetricCollector:
"""指标收集器"""
def record(self, name: str, value: float, tags: Dict = None):
print(f"[METRIC] {name}={value} tags={tags}")
class SafetyFilter:
"""安全过滤器"""
def check(self, text: str) -> tuple[bool, str]:
# 实际实现:调用内容安全 API
if "密码" in text.lower():
return False, "检测到敏感信息请求"
return True, ""
class CircuitBreaker:
"""熔断器"""
def __init__(self, failure_threshold=5, recovery_time=30):
self.failure_count = 0
self.failure_threshold = failure_threshold
self.recovery_time = recovery_time
self.last_failure_time = None
self.state = "CLOSED" # CLOSED, OPEN, HALF_OPEN
def call(self, func: Callable, *args, **kwargs):
if self.state == "OPEN":
if time.time() - self.last_failure_time > self.recovery_time:
self.state = "HALF_OPEN"
else:
raise Exception("Circuit breaker is OPEN")
try:
result = func(*args, **kwargs)
if self.state == "HALF_OPEN":
self.state = "CLOSED"
self.failure_count = 0
return result
except Exception as e:
self.failure_count += 1
self.last_failure_time = time.time()
if self.failure_count >= self.failure_threshold:
self.state = "OPEN"
raise e
class PromptRegistry:
"""Prompt 版本注册中心"""
def __init__(self):
self.versions = {}
def register(self, name: str, version: str, template: str):
key = f"{name}@{version}"
self.versions[key] = template
def get(self, name: str, version: str = "latest") -> str:
if version == "latest":
versions = [k for k in self.versions if k.startswith(f"{name}@")]
return self.versions[sorted(versions)[-1]]
return self.versions.get(f"{name}@{version}")
# ==================== 上下文工程层 ====================
@dataclass
class Document:
content: str
source: str
score: float = 0.0
class VectorStore:
"""向量数据库封装"""
def __init__(self):
self.documents = []
def add_documents(self, docs: List[Document]):
self.documents.extend(docs)
def search(self, query: str, top_k: int = 5) -> List[Document]:
# 实际实现:调用向量数据库 API
# 这里模拟返回结果
return [
Document(content="退换货政策:7天无理由退货", source="policy.pdf", score=0.95),
Document(content="退款将在3-5个工作日到账", source="faq.md", score=0.88),
][:top_k]
class ConversationMemory:
"""对话记忆管理"""
def __init__(self, max_turns: int = 10):
self.turns = []
self.max_turns = max_turns
def add(self, user_msg: str, assistant_msg: str):
self.turns.append({"user": user_msg, "assistant": assistant_msg})
if len(self.turns) > self.max_turns:
self.turns = self.turns[-self.max_turns:]
def get_formatted(self) -> str:
formatted = []
for turn in self.turns:
formatted.append(f"用户: {turn['user']}")
formatted.append(f"助手: {turn['assistant']}")
return "\n".join(formatted)
# ==================== Prompt 工程层 ====================
class PromptBuilder:
"""Prompt 构建器"""
FAQ_TEMPLATE = """你是一位专业的客服助手。请基于以下参考资料回答用户问题。
## 参考资料
{context}
## 对话历史
{history}
## 用户问题
{query}
请用中文回答,保持礼貌和专业。如果参考资料中没有答案,请说"抱歉,我暂时无法回答这个问题,建议联系人工客服"。"""
AGENT_TEMPLATE = """你是一个智能客服 Agent,可以使用以下工具帮助用户:
{tools_description}
## 可用工具
{tools}
请按照以下格式思考并行动:
Thought: 你的思考过程
Action: 工具名称
Action Input: 工具输入参数
## 对话历史
{history}
## 用户问题
{query}
开始:"""
@classmethod
def build_faq_prompt(cls, query: str, context: List[Document], history: str) -> str:
context_str = "\n\n".join([
f"[来源: {doc.source}]\n{doc.content}" for doc in context
])
return cls.FAQ_TEMPLATE.format(
context=context_str,
history=history,
query=query
)
@classmethod
def build_agent_prompt(cls, query: str, history: str, tools: List[Dict]) -> str:
tools_desc = "\n".join([
f"- {t['name']}: {t['description']}" for t in tools
])
return cls.AGENT_TEMPLATE.format(
tools_description=tools_desc,
tools=tools_desc,
history=history,
query=query
)
# ==================== 模型层 ====================
class LLMClient:
"""LLM 客户端"""
def __init__(self, model: str = "gpt-4o"):
self.model = model
self.circuit_breaker = CircuitBreaker()
def generate(self, prompt: str, max_tokens: int = 500) -> str:
def _call():
# 实际实现:调用 OpenAI/Anthropic API
time.sleep(0.5) # 模拟延迟
return f"[模拟回复] 基于您的提问,我为您找到了以下信息..."
return self.circuit_breaker.call(_call)
# ==================== 业务编排层 ====================
class IntentType(Enum):
FAQ = "faq"
COMPLEX = "complex"
HUMAN_HANDOFF = "human"
class IntentClassifier:
"""意图分类器"""
def classify(self, query: str) -> IntentType:
# 实际实现:调用分类模型
if any(kw in query for kw in ["怎么", "如何", "什么", "吗"]):
return IntentType.FAQ
elif any(kw in query for kw in ["投诉", "退款", "人工"]):
return IntentType.HUMAN_HANDOFF
return IntentType.COMPLEX
class SmartCustomerService:
"""智能客服系统 - 三工程协同"""
def __init__(self):
# Harness 组件
self.metrics = MetricCollector()
self.safety = SafetyFilter()
self.registry = PromptRegistry()
# 上下文组件
self.vector_store = VectorStore()
self.memory = ConversationMemory()
# Prompt 组件
self.prompt_builder = PromptBuilder()
# 模型组件
self.llm = LLMClient()
self.classifier = IntentClassifier()
def handle(self, user_query: str, user_id: str = "anonymous") -> Dict:
start_time = time.time()
# 1. Harness: 安全过滤
is_safe, reason = self.safety.check(user_query)
if not is_safe:
self.metrics.record("safety_blocked", 1, {"reason": reason})
return {
"answer": f"您的请求涉及安全问题:{reason}",
"source": "safety_filter",
"latency": time.time() - start_time
}
# 2. 意图识别
intent = self.classifier.classify(user_query)
# 3. 根据意图选择处理路径
if intent == IntentType.FAQ:
answer = self._handle_faq(user_query)
elif intent == IntentType.COMPLEX:
answer = self._handle_complex(user_query)
else:
answer = "正在为您转接人工客服,请稍候..."
# 4. 更新记忆
self.memory.add(user_query, answer)
# 5. Harness: 记录指标
latency = time.time() - start_time
self.metrics.record("request_latency", latency, {"intent": intent.value})
return {
"answer": answer,
"intent": intent.value,
"latency": latency
}
def _handle_faq(self, query: str) -> str:
# 上下文工程:检索相关知识
docs = self.vector_store.search(query, top_k=3)
# 上下文工程:获取对话历史
history = self.memory.get_formatted()
# Prompt 工程:构建 Prompt
prompt = self.prompt_builder.build_faq_prompt(query, docs, history)
# Harness: 调用模型
response = self.llm.generate(prompt, max_tokens=300)
return response
def _handle_complex(self, query: str) -> str:
# 复杂问题使用 Agent 模式
history = self.memory.get_formatted()
tools = [
{"name": "search_order", "description": "查询订单信息"},
{"name": "check_inventory", "description": "查询库存"},
]
prompt = self.prompt_builder.build_agent_prompt(query, history, tools)
response = self.llm.generate(prompt, max_tokens=800)
return response
# ==================== 使用示例 ====================
if __name__ == "__main__":
# 初始化系统
cs = SmartCustomerService()
# 预加载知识库
cs.vector_store.add_documents([
Document(content="退换货政策:7天无理由退货", source="policy.pdf"),
Document(content="退款将在3-5个工作日到账", source="faq.md"),
Document(content="会员可享受9折优惠", source="member.md"),
])
# 模拟对话
queries = [
"我想退货,怎么操作?",
"退款多久能到账?",
"帮我查一下订单 12345 的状态",
]
for q in queries:
print(f"\n{'='*50}")
print(f"用户: {q}")
result = cs.handle(q)
print(f"助手: {result['answer']}")
print(f"[意图: {result['intent']}, 延迟: {result['latency']:.2f}s]")
十一、行业趋势与展望
11.1 从 Prompt Engineering 到 AI Engineering
2022: Prompt Engineering(提示词调优)
v
2023: RAG + Context Engineering(知识增强)
v
2024: Agent + Multi-Agent(自主决策)
v
2025+: AI Engineering / Harness Engineering(系统工业化)
+-> 评估驱动、数据飞轮、持续交付
11.2 新兴技术方向
| 方向 | 说明 | 代表项目 |
|---|---|---|
| DSPy | 编程式 Prompt 优化框架 | Stanford DSPy |
| Prompt 优化器 | 自动搜索最优 Prompt | AutoPrompt, OPRO |
| 模型路由 | 根据查询复杂度自动选择模型 | Martian, Not Diamond |
| 合成数据生成 | 用 LLM 生成评估/训练数据 | SynthID, GlaDOS |
| 可解释 AI | 追踪模型决策过程 | SHAP, LIME for LLM |
11.3 关键认知转变
- 从"调 Prompt"到"建系统":Prompt 只是系统的一个可配置参数
- 从"人工评估"到"自动评估":建立可量化的评估指标体系
- 从"单点优化"到"数据飞轮":让生产数据自动驱动系统迭代
- 从"黑盒"到"白盒":全链路可观测、可追踪、可审计
- 从"实验"到"产品":用软件工程的严谨性对待 AI 应用
十二、参考资源
12.1 开源工具
| 类别 | 工具 | 说明 |
|---|---|---|
| 编排框架 | LangChain, LlamaIndex, Semantic Kernel | 应用编排 |
| 评估框架 | deepeval, ragas, trulens | 自动化评估 |
| 监控平台 | LangSmith, Langfuse, Arize | 可观测性 |
| Prompt 管理 | PromptLayer, Weights & Biases | 版本管理 |
| 安全工具 | Guardrails AI, Lakera, Prompt Armor | 内容安全 |
| 向量数据库 | Pinecone, Weaviate, Milvus, Qdrant | 知识检索 |
结语 :Harness 工程不是对 Prompt 工程和上下文工程的替代,而是将二者纳入一个更宏大的工程化框架中。在 AI 应用从"Demo"走向"Production"的过程中,Harness 工程提供了必要的方法论、工具链和组织实践,帮助团队以可持续的方式构建和运营 AI 产品。