几年前,许多人,甚至是顶尖的人工智能研究人员,都声称prompt engineering现在已经死了。
显然,他们错了,事实上,迅速的工程现在比以往任何时候都更加重要。它是如此重要,以至于它现在被重新命名为上下文工程。
是的,这是另一个奇特的术语,用于描述调整LLM有效执行其任务所需的指令和相关上下文的重要过程。
关于上下文工程已经写了很多 (Ankur Goyal,Walden Yan,Tobi Lutke,和安德烈·卡尔萨斯),但我想写下我对该主题的想法,并向您展示一个具体的分步指南,在开发AI代理工作流程中将上下文工程付诸实践。
我不完全确定是谁创造了上下文工程,但我们将在这个数字的基础上Dex Horthy这简要解释了什么是上下文工程。

我喜欢上下文工程这个术语,因为它感觉像是一个更广泛的术语,可以更好地解释快速工程中的大部分工作,包括其他相关任务。
关于提示工程是一项严肃技能的疑问是,许多人将其与盲目提示 (您在像ChatGPT这样的LLM中使用的简短任务描述) 混淆。在盲目提示中,你只是问系统一个问题。在提示工程中,您必须更仔细地考虑提示的上下文和结构。也许它应该从早期就被称为上下文工程。
上下文工程是下一阶段,在这个阶段,你要构建完整的上下文,在许多情况下,这需要超越简单的提示,进入更严格的方法来获取、增强和优化系统的知识。
从开发人员的角度来看,上下文工程涉及一个迭代过程,以优化指令和您提供的LLM上下文,以实现所需的结果。这包括使用正式的流程 (例如eval管道) 来衡量您的策略是否有效。
鉴于人工智能领域的快速发展,我建议对上下文工程进行更广泛的定义:为llm和高级AI模型设计和优化指令和相关上下文以有效执行其任务的过程。这不仅包括基于文本的llm,还包括优化多模态模型的上下文,这些模型正变得越来越普遍。这可能包括所有即时工程工作和相关流程,例如:
换句话说,您试图在上下文工程中实现的是优化您在LLM的上下文窗口中提供的信息。这也意味着过滤掉嘈杂的信息,这本身就是一门科学,因为它需要系统地测量LLM的性能。
每个人都在写上下文工程,但在这里我们将向您介绍一个具体的例子,说明在构建AI代理时上下文工程是什么样子的。
让我们看一下我最近为个人使用而构建的多智能体深度研究应用程序所做的一些上下文工程工作的具体示例。
构建了代理工作流,但该工具无关紧要。我构建的完整代理架构如下所示:

我的工作流中的Search Planner代理负责根据用户查询生成搜索计划。
下面是我为这个子代理组合在一起的系统提示:
此提示有许多部分需要仔细考虑我们为计划代理提供的确切上下文以有效地执行任务。正如你所看到的,这不仅仅是设计一个简单的提示或指令; 这个过程需要实验,并为模型提供重要的上下文,以最佳地执行任务。
让我们将问题分解为核心组件,这些组件是有效上下文工程的关键。
您是一名专家级研究规划师。
您的任务是将复杂的研究查询(由<user_query>最新AI前沿技术是什么?</user_query>界定)
拆分为具体的搜索子任务,每个子任务专注于研究查询的不同方面或不同数据源类型。
当前日期和时间是:{{ $ now.toISO() }}
对于每个子任务,请提供:
子任务的唯一字符串ID(例如,'subtask_1','news_update')
集中于主查询一个方面的具体搜索查询
搜索的数据源类型(网络、新闻、学术、专业)
时间相关性(今天、上周、最近、过去一年、全部时间)
如果适用,领域重点(技术、科学、健康等)
优先级水平(1-最高到5-最低)
所有字段(id、query、source_type、time_period、domain_focus、priority)
对于每个子任务都是必需的,除了time_period和domain_focus,
如果无关紧要则可以为空。
创建两个子任务,它们共同将提供该主题的全面覆盖。
重点关注不同的方面、视角或信息来源。
每个子任务将包括以下信息:id: strquery: strsource_type: str
# 例如,“web”,“news”,“academic”,“specialized”time_period: Optional[str] = None
# 例如,“today”,“last week”,“recent”,“past_year”,“all_time”domain_focus: Optional[str] = None
# 例如,“technology”,“science”,“health”priority: int
# 1(最高)到5(最低)在获取上述子任务信息后,您将添加两个额外字段,
对应于start_date和end_date。根据当前日期和所选的时间段推断这些信息。
start_date和end_date应使用以下示例中的格式:“start_date”: “2024-06-03T06:00:00.000Z”,“end_date”: “2024-06-11T05:59:59.999Z”,指令是提供给系统的高级指令,以指示它确切地做什么。
您是一名专家级研究规划师。
您的任务是将复杂的研究查询(<user_query>最新AI前沿技术是什么?</user_query>)
拆分为具体的搜索子任务,每个子任务专注于研究查询的不同方面或不同数据源类型。许多初学者,甚至经验丰富的AI开发人员都会止步于此。鉴于我分享了上面的完整提示,你可以理解我们需要给系统提供更多的上下文,让它按照我们的意愿工作。这就是上下文工程的全部内容; 它向系统提供了有关问题范围的更多信息,以及我们确切希望从中获得的细节。
用户输入未显示在系统提示中,但下面是它的外观示例。
<user_query>最新AI前沿技术是什么?</user_query>请注意分隔符的使用,这是关于更好地构造提示。这对于避免混淆很重要,并增加了用户输入是什么以及我们希望系统生成什么内容的清晰度。有时,我们输入的信息类型与我们希望模型输出的内容有关 (例如,查询是输入,子查询是输出)。
除了高级指令和用户输入之外,您可能已经注意到,我在与计划代理需要生成的子任务相关的细节上花费了大量精力。下面是我向规划代理提供的详细说明,用于创建给定用户查询的子任务。
对于每个子任务,请提供:
子任务的唯一字符串ID(例如,'subtask_id','news_update')
集中于主查询一个方面的具体搜索查询
搜索的数据源类型(网络、新闻、学术、专业)
时间相关性(今天、上周、最近、过去一年、全部时间)
如果适用,领域重点(技术、科学、健康等)
优先级水平(1-最高到5-最低)
所有字段(id、query、source_type、time_period、domain_focus、priority)
对于每个子任务都是必需的,除了time_period和domain_focus,
如果无关紧要则可以为空。
创建两个子任务,它们共同将提供该主题的全面覆盖。
重点关注不同的方面、视角或信息来源。如果您仔细查看上面的说明,我已经决定构建一个我希望规划代理生成的所需信息的列表,以及一些提示/示例,以更好地帮助引导数据生成过程。这对于为代理提供有关预期内容的附加上下文至关重要。例如,如果您不告诉它您希望优先级在1-5的范围内,那么系统可能更喜欢使用1-10的范围。同样,这个背景很重要!
接下来,让我们谈谈结构化输出。为了从规划代理获得一致的输出,我们还提供了一些关于我们期望的子任务格式和字段类型的上下文。下面是我们作为附加上下文传递给代理的示例。这将为代理提供关于我们期望的输出的提示和线索:
每个子任务将包括以下信息:id: strquery: strsource_type: str
# 例如,“web”,“news”,“academic”,“specialized”time_period: Optional[str] = None
# 例如,“today”,“last week”,“recent”,“past_year”,“all_time”domain_focus: Optional[str] = None
# 例如,“technology”,“science”,“health”priority: int
# 1(最高)到5(最低)在获取上述子任务信息后除此之外,您还可以使用工具输出解析器,该工具本质上将用于构建最终输出。我使用的选项是提供一个JSON示例如下:
{
"subtasks": [
{
"id": "openai_latest_news",
"query": "latest OpenAI announcements and news",
"source_type": "news",
"time_period": "recent",
"domain_focus": "technology",
"priority": 1,
"start_date": "2025-06-03T06:00:00.000Z",
"end_date": "2025-06-11T05:59:59.999Z"
},
{
"id": "openai_official_blog",
"query": "OpenAI official blog recent posts",
"source_type": "web",
"time_period": "recent",
"domain_focus": "technology",
"priority": 2,
"start_date": "2025-06-03T06:00:00.000Z",
"end_date": "2025-06-11T05:59:59.999Z"
},
...
}然后,该工具将从这些示例中自动生成模式,从而允许系统解析并生成适当的结构化输出,如下面的示例所示:
[
{
"action": "parse",
"response": {
"output": {
"subtasks": [
{
"id": "subtask_1",
"query": "OpenAI recent announcements OR news OR updates",
"source_type": "news",
"time_period": "recent",
"domain_focus": "technology",
"priority": 1,
"start_date": "2025-06-24T16:35:26.901Z",
"end_date": "2025-07-01T16:35:26.901Z"
},
{
"id": "subtask_2",
"query": "OpenAI official blog OR press releases",
"source_type": "web",
"time_period": "recent",
"domain_focus": "technology",
"priority": 1.2,
"start_date": "2025-06-24T16:35:26.901Z",
"end_date": "2025-07-01T16:35:26.901Z"
}]}}}]这个东西看起来很复杂,但是今天的许多工具都可以实现开箱即用的结构化输出功能,因此您可能不需要自己实现它。使上下文工程的这一部分变得轻而易举。这是上下文工程的一个被低估的方面,我看到许多AI开发人员出于某种原因忽略了这一点。希望上下文工程能够更多地阐明这些重要技术。这是一种非常强大的方法,尤其是当您的代理获得不一致的输出时,这些输出需要以特殊格式传递给工作流中的下一个组件。
我们正在使用来构建我们的代理,因此很容易将当前日期和时间放在上下文中。你可以这样做:
The current date and time is: {{ $now.toISO() }}这是一个简单,方便的函数被调用,但通常将其构建为专用工具,可以帮助使事情更加动态 (即e.,仅在查询需要时获取日期和时间)。这就是上下文工程的意义。它迫使你,建设者,做出具体的决定,什么情况下传递给LLM。这是伟大的,因为它消除了假设和不准确的应用程序。
日期和时间是系统的重要上下文; 否则,它往往无法很好地执行需要了解当前日期和时间的查询。例如,如果我要求系统搜索上周发生的来自OpenAI的最新开发新闻,它只会猜测日期和时间,这将导致次优查询,因此,不准确的网络搜索。当系统具有正确的日期和时间时,它可以更好地推断日期范围,这对于搜索代理和工具很重要。我添加了这个作为上下文的一部分,以允许LLM生成日期范围:
After obtaining the above subtasks information, you will add two extra fields. Those correspond to start_date and end_date. Infer this information given the current date and the time_period selected. start_date and end_date should use the format as in the example below:"start_date": "2024-06-03T06:00:00.000Z","end_date": "2024-06-11T05:59:59.999Z",我们专注于架构的规划代理,因此我们不需要在这里添加太多工具。唯一有意义的其他工具是一个检索工具,它可以在给定查询的情况下检索相关的子任务。让我们在下面讨论这个想法。