我们都有过这样的经历:与AI“搏斗”,试图让它完成特定的任务。你不断调整Prompt,重新措辞,添加更多细节,或许在尝试了五次之后,才能勉强得到一个接近你想要的结果。这种挣扎使人们将注意力集中在 “Prompt工程” 上,认为它是释放AI潜力的关键。但是,如果我告诉你,仅仅关注Prompt就像试图只写一句台词来导演一部大片一样呢?台词很重要,但它忽略了整个制作过程:场景设计、角色背景、灯光和剧本。欢迎来到上下文工程的世界。

上下文工程:AI的整体环境设计

上下文工程不仅仅是一个新的流行语;它是我们构建和与AI系统交互方式的根本转变。虽然Prompt工程是关于构建完美的问题,但上下文工程是关于设计AI成功的完美环境。它是一门架构整个信息、规则和工具宇宙的学科,AI可以在决策时访问这些信息、规则和工具。正如Shopify首席执行官Tobi Lütke恰如其分地指出的那样,它是“为LLM提供所有上下文,使其能够合理地解决任务的艺术”。简单来说,上下文工程关注的是如何为大模型提供完成任务所需的完整背景信息。

与传统的Prompt工程不同,上下文工程更加注重为AI系统提供丰富的背景知识和明确的行动框架,从而提升AI的理解能力和问题解决能力。例如,在客户服务场景中,传统的Prompt可能只是简单地询问:“客户遇到了什么问题?”而上下文工程则会提供更详细的信息,包括客户的购买历史、之前的沟通记录、产品说明书等,从而使AI能够更准确地理解客户的需求并提供个性化的解决方案。

上下文的完整频谱:多层信息架构

当我们谈论“上下文”时,我们谈论的是AI“上下文窗口”内的所有内容——它针对给定任务的短期记忆。一个掌握上下文工程的专家不仅仅是将信息倾倒到这个窗口中;他们以刻意的方式分层构建它。

把它想象成构建一个智能代理的“简报包”。这个包有几个不同的层:

  1. 角色与指令层(“谁”):这是定义AI的身份、目的和行为规则的基础层。它是为所有后续交互奠定基础的系统Prompt

    • 角色:AI应该扮演什么角色?一个乐于助人的客户服务代理?一个愤世嫉俗的营销专家?一个一丝不苟的代码审查员?
    • 语气:它应该使用什么风格?正式、随意、同情、幽默?
    • 规则:有哪些硬性约束?“永远不要提供医疗建议。”“始终引用你的来源。”“仅以JSON格式回复。”
    • 目标:它的主要目标是什么?解决客户工单,产生创意,准确总结信息?

    举例来说,如果目标是构建一个能够撰写营销文案的AI,那么角色可以是“经验丰富的营销专家”,语气可以是“创意十足且充满激情”,规则可以是“文案必须符合品牌形象,避免夸大宣传”,目标则是“撰写能够吸引目标受众并提升品牌知名度的文案”。通过明确这些信息,可以引导AI生成更符合要求的文案。

  2. 知识层(“什么”):这是AI执行其任务所需的外部信息。这就是检索增强生成(RAG)发挥作用的地方。AI不仅仅依赖其训练数据,还会被授予访问新鲜、相关信息的能力。

    • 文档:用户手册中的块,公司政策文件或最新的财务报告。
    • 数据库:从SQL或NoSQL数据库检索的结构化数据。
    • 实时数据:来自API的信息,例如当前天气、股票价格或新闻头条。

    例如,如果AI需要撰写一篇关于特定产品的文章,那么知识层可以包括产品说明书、用户评价、竞争对手的产品信息等。通过检索这些信息,AI可以更全面地了解产品,从而撰写出更具深度和价值的文章。RAG 技术允许模型在生成文本之前从外部知识源检索信息,这对于处理需要最新或特定领域知识的任务至关重要。

  3. 记忆层(“我们去过哪里”):没有记忆的AI注定要重复自己,并且无法进行连贯的多轮对话。

    • 短期记忆:当前对话的历史记录。这使AI能够理解代词并遵循对话流程。
    • 长期记忆:存储在向量数据库中的过去对话的摘要或关于用户的关键事实。这允许真正的个性化,AI可以记住你的偏好以及跨不同会话的过去交互。

    例如,一个客户服务AI可以记住用户之前的咨询内容、购买记录、偏好设置等,从而在后续的对话中提供更加个性化的服务。这不仅可以提高用户满意度,还可以节省用户的时间和精力。长期记忆通过向量数据库实现,使得 AI 能够跨会话保持用户信息的连续性。

  4. 工具层(“如何”):该层赋予AI超出生成文本之外的能力。这是你授予它与外部世界互动的代理权的方式。

    • 函数定义:你定义AI可以调用的特定函数,例如send_email,query_database或get_user_calendar。
    • 工具使用说明:你告诉AI何时以及如何使用这些工具。

    例如,一个AI助手可以使用send_email函数发送邮件,使用query_database函数查询数据库,使用get_user_calendar函数获取用户日历信息。通过这些工具,AI可以完成更加复杂的任务,例如预定会议、发送提醒、生成报告等。这种能力扩展了 AI 的应用范围,使其能够执行更实际的任务。

  5. 工作流层(“下一步是什么”):对于复杂的任务,一次AI调用是不够的。工作流或“链”将大型任务分解为一系列较小的、可管理的步骤,每个步骤都有其自己的优化上下文。这是代理行为的核心。

    例如,如果用户要求“总结我与Jane的上次会议并起草一封后续电子邮件”,试图一次完成此操作是失败的根源。

    分解任务。

    • 步骤1(工具使用):在联系人中找到“Jane”以获取她的全名和电子邮件。
    • 步骤2(RAG):在用户的日历/笔录中搜索与Jane的上次会议。
    • 步骤3(总结):获取笔录并进行总结。
    • 步骤4(起草):获取摘要并起草电子邮件,使用上下文中定义的角色和语气。

    每个步骤都涉及调用LLM(或其他服务),并为该子任务专门设计了上下文。这种模块化的方法使得复杂的任务可以分解成更小、更容易管理的部分,从而提高效率和准确性。

上下文工程师的最佳实践:构建高效智能的AI

从理论到实践需要一种严谨的方法。以下是指导你的上下文工程工作的四个关键最佳实践。

  1. 清晰胜于数量:避免“数据转储”

    最常见的错误是假设更多的上下文总是更好。用不相关的信息淹没上下文窗口会产生噪音,使模型感到困惑,并且实际上会降低性能。这就是“大海捞针”问题。

    最佳实践:在主要的LLM调用之前,使用预处理步骤。这可能是另一个更简单的LLM调用或基于嵌入的搜索,以从你的知识源中识别和提取最相关的片段。你的目标是提供简洁、高信号的简报,而不是图书馆。

    例如,在处理大量文档时,首先使用一个AI模型对文档进行筛选,只保留与用户查询相关的文档,然后再将这些文档作为上下文提供给主要的AI模型。这可以避免模型被不相关的信息分散注意力,从而提高其性能。一个有效的预处理步骤能够显著减少噪音,提高上下文的相关性。

  2. 结构至上:说AI的语言

    LLM最好使用清晰、结构化的信息。使用明确定义的格式和分隔符有助于模型区分上下文中不同的部分(指令与数据与用户查询)。

    最佳实践:使用Markdown,XML标签或JSON来划分Prompt中的各个部分。当你期望结构化输出时,请提供清晰的架构或几个所需格式的示例。这可以大大提高可靠性,并使输出可以在编程中使用。

    例如,如果希望AI以JSON格式返回数据,那么需要在Prompt中明确JSON的结构,并提供一些示例。这可以帮助AI更好地理解期望的输出格式,从而提高输出的准确性。结构化信息不仅易于解析,而且还能提高 AI 的理解能力。

  3. 动态上下文为王:为适应性而构建

    静态的,硬编码的上下文是脆弱的。一个健壮的AI系统为每个交互动态地构建其上下文。

    最佳实践:你的应用程序代码应负责协调上下文。根据用户的查询,它应该决定检索哪些文档,提供哪些工具以及显示哪些记忆。发送到LLM的最终Prompt应该是定制的工件,完全针对手头的任务量身定制。

    例如,如果用户提出的问题涉及到特定主题,那么应用程序应该能够自动检索与该主题相关的文档,并将它们作为上下文提供给AI模型。这种动态调整上下文的能力可以使AI更好地适应不同的用户需求。一个动态的上下文构建过程可以确保 AI 始终拥有完成任务所需的最新和最相关的信息。

  4. 以工作流思考,而不是单次调用

    对于超出简单问答的任何事情,你需要从多步骤工作流的角度进行思考。如果用户问“总结我与Jane的上次会议并起草一封后续电子邮件”,试图一次完成此操作是失败的根源。

    最佳实践:分解任务。每个步骤都涉及调用LLM(或其他服务),并为该子任务专门设计了上下文。

    例如,将“撰写一篇关于特定产品的文章”的任务分解为“收集产品信息”、“分析用户评价”、“撰写文章草稿”、“修改文章”等步骤,每个步骤都使用不同的Prompt和上下文。这种分解任务的方法可以提高效率和准确性,并使任务更容易管理。工作流使得复杂的任务可以分解成更小、更易于管理的部分,从而提高整体效率和质量。

代码层面的上下文工程:实践案例

让我们具体一点。以下是一些Python风格的伪代码示例,展示了如何构建这些上下文“子句”。

子句1:角色与指令子句

这奠定了基础。这是你上下文中首先要放的东西,应该清楚地分开。

def create_persona_clause(role, tone, rules):
    """为AI构建基础指令块。"""

    persona_prompt = f"""<persona>你是具有以下角色的AI助手:{role}。
你的语气应该是:{tone}。
你必须遵守以下规则:<rules>"""
    for rule in rules:
        persona_prompt += f"- {rule}\n"
    persona_prompt += """</rules></persona>"""
    return persona_prompt

# --- 示例用法 ---
role = "高级财务分析师"
tone = "专业、数据驱动且略带怀疑"
rules = [
    "永远不要提供明确的投资建议。",
    "始终参考文档和页码来引用任何数据。",
    "如果未提供文档,请说明你无法回答该问题。",
    "以JSON对象输出你的最终分析。"
]

persona_clause = create_persona_clause(role, tone, rules)
print(persona_clause)

子句2:结构化输出子句

为了获得可靠的JSON,向模型准确展示你想要什么。

def create_structured_output_clause():
    """定义所需的JSON输出格式。"""
    json_structure_prompt = """<output_format>以有效的JSON对象提供你的最终分析,该对象具有以下结构。不要包含JSON块之外的任何文本或解释。
{
  "summary": "财务状况的简要单句总结。",
  "key_metrics": {
    "revenue_growth_qoq": "季度收入环比增长的百分比。",
    "net_profit_margin": "净利润率(百分比)。",
    "debt_to_equity_ratio": "计算的债务权益比率。"
  },
  "risks": [
    {
      "risk_factor": "潜在风险的描述。",
      "severity": "低、中或高",
      "source_document": "识别此风险的文档。",
      "page_number": "来源的页码。"
    }
  ],
  "confidence_score": "一个介于0.0到1.0之间的分数,表示你对此分析的信心,基于所提供的数据。"
}</output_format>"""
    return json_structure_prompt

structured_output_clause = create_structured_output_clause()

子句3:动态知识子句(RAG)

这是你的应用程序逻辑大放异彩的地方。你获取数据并注入它。

def create_dynamic_knowledge_clause(query, vector_db):
    """获取相关文档并将它们添加到上下文中。"""

    # 在实际应用中,这将执行相似性搜索
    relevant_docs = vector_db.search(query, top_k=3)

    knowledge_prompt = "<knowledge_sources>\n"
    knowledge_prompt += "你必须仅基于以下文档进行分析:\n"
    for doc in relevant_docs:
        knowledge_prompt += f"""<document name="{doc['name']}"><content>{doc['text_snippet']}</content><metadata>页码:{doc['page_number']}</metadata></document>"""
    knowledge_prompt += "</knowledge_sources>\n"
    return knowledge_prompt

# --- 伪代码用法 ---
# user_query = "最新季度报告中的主要风险是什么?"
# knowledge_clause = create_dynamic_knowledge_clause(user_query, my_vector_database)

组装最终上下文

现在,你将这些子句组合在一起,以构建LLM调用的完整上下文。

def build_final_context(persona, knowledge, structured_output, user_query):
    """将所有上下文子句组装成LLM的最终Prompt。"""
    final_prompt = f"""{persona}{knowledge}{structured_output}基于以上所有信息和说明,请分析提供的文档以回答以下用户请求。<user_request>{user_query}</user_request>"""
    return final_prompt

# --- 将所有内容放在一起 ---
# final_context = build_final_context(
#     persona_clause,
#     knowledge_clause,
#     structured_output_clause,
#     user_query
# )
# response = llm_api.generate(prompt=final_context)

未来:上下文感知

上下文工程正在从一种手工技艺发展成为一种自动化的科学。下一代AI开发平台不仅将提供对模型的访问;它们还将提供用于管理上下文的复杂工具。我们正在朝着AI系统可以:

  • 自动管理自己的上下文:无需明确的指令即可确定哪些信息是相关的。
  • 保持持久记忆:从每次交互中学习,以建立对用户和领域的深刻、不断发展的理解。
  • 编排复杂的代理工作流程:将模棱两可的目标分解为具体的计划并自主执行它们。

通过掌握今天的上下文工程原理,你不仅在构建更好的AI应用程序,而且在为未来真正智能、可靠和不可或缺的系统奠定基础。你正在超越成为一个Prompt编写者,而成为一个真正的智能架构师。 通过不断迭代和优化上下文工程,我们可以构建出更智能、更可靠、更符合人类需求的AI系统。

总而言之,上下文工程的崛起标志着 AI 开发理念的转变,它超越了单纯的Prompt调整,转向构建更丰富、更动态、更具适应性的 AI 环境。 掌握上下文工程,意味着掌握了构建未来 AI 的关键。