深度解析AI智能体四条上下文工程管理法则


智能体代理需要上下文来执行任务。上下文工程是一门艺术和科学,它能够在代理轨迹的每一步中,用恰当的信息填充上下文窗口。在本文中,我将上下文工程归纳为几种常见策略,这些策略在当今许多流行的代理中都较为常见。

Agent智能体是啥?上下文又是啥?
我们先来认识两个关键词:Agent和上下文(Context)。

Agent智能体:聪明的小助手
你们可以把Agent想象成一个特别聪明的小助手,它不是那种只会傻乎乎回答问题的机器人,而是能像我们人一样思考、做决策,甚至还能使用各种工具来完成复杂任务的小能手。

举个例子,你想让Agent帮你写一篇关于“AI对未来教育的影响”的报告。它可能会先去网上搜集资料(用“搜索工具”),然后整理信息,列出提纲,再根据提纲开始写作,写完后还会自己检查一遍有没有语法错误或者内容不完善的地方(自我修正)。这一系列操作,就展现了Agent的厉害之处。

上下文:Agent智能体的“工作记忆”
那上下文又是什么呢?你们可以把Agent想象成一个大脑,而它的上下文窗口(Context Window)就是这个大脑的“工作记忆”。

就像我们人一样,我们做事情的时候,会把当前需要的信息都放在脑子里,方便随时调用。比如你在解一道数学题,草稿纸上写下的公式、计算步骤,以及题目给出的条件,这些都是你的“工作记忆”。

Agent也是一样,它在处理任务的时候,需要把指令、之前聊过的对话、从工具那里得到的信息等等,都塞到它的“工作记忆”(上下文窗口)里,这样它才能理解你在说什么,才能知道接下来该干嘛。

为什么Agent需要“上下文工程”?
问题来了,这个“工作记忆”是不是越大越好呢?当然不是!就像我们的草稿纸,地方是有限的。Agent的上下文窗口也有大小限制,不可能把所有信息都塞进去。而且,信息越多,它处理起来就越慢,花费的钱也越多,甚至还可能“脑子乱了”,表现得不好。

这就引出了我们今天的主角——上下文工程

上下文工程,简单来说,就是一门“艺术”和“科学”,教我们怎么在Agent的每一步操作中,往它的“工作记忆”里塞入“刚刚好”的信息。不多不少,恰到好处!就像一个厉害的厨师,知道什么时候放多少调料,才能做出最美味的菜肴。

上下文工程要管哪些信息?
它主要管理以下几种信息:

  • 指令(Instructions):你给Agent下的命令,它记住的事情,或者你给它的范例,以及各种工具的使用说明。
  • 知识(Knowledge):各种事实、信息。
  • 工具(Tools):Agent调用工具后得到的反馈结果。

Agent在“上下文”上遇到的烦恼
Agent虽然聪明,但它在处理长时间、多步骤任务的时候,最容易遇到“上下文”的烦恼。想象一下,你写一篇论文,越写越长,草稿纸也写得密密麻麻,是不是有时候自己都会看晕?Agent也会:

  • 上下文爆满(Exceed Context Window):信息太多,超过了“工作记忆”的容量。
  • 花费飙升、速度变慢(Balloon Cost / Latency):信息越多,处理起来越费钱,速度也越慢。
  • 表现变差(Degrade Agent Performance):信息太多太杂,Agent反而会“犯迷糊”,犯各种错误:
    • 上下文“中毒”(Context Poisoning):Agent自己瞎编乱造的信息,结果被它当真了,还保存起来,后面就一直错下去。
    • 上下文“分心”(Context Distraction):信息太多太杂,让Agent抓不住重点,不知道该关注哪一部分。
    • 上下文“糊涂”(Context Confusion):一些没用的信息混进来,影响了Agent的判断。
    • 上下文“冲突”(Context Clash):不同信息之间自相矛盾,把Agent搞懵了。
所以说,对于那些开发AI Agent的工程师来说,“上下文工程”简直就是他们的头等大事!因为它直接决定了Agent能不能聪明地、高效地完成任务。

“上下文工程”的四大绝招!
面对这些挑战,工程师们想出了很多办法。我把它们总结成四大绝招:写、选、压、隔

绝招一:写上下文(Write Context)
这个绝招的意思是,把重要的信息保存到“工作记忆”外面,等需要的时候再拿回来用。

  • “草稿本”(Scratchpads) 就像我们写作业时,旁边会放个草稿本记下一些重要的步骤或者想法。Agent也有自己的“草稿本”。当它在处理一个比较复杂的任务时,它可以把一些关键的计划、中间结果记下来,存到这个“草稿本”里。这样即使它的“工作记忆”被清空了,这些重要的信息也不会丢,以后还能拿出来用。
    这个“草稿本”可以是一个文件,也可以是Agent内部的一个变量,反正就是用来临时存储重要信息的。
  • “长期记忆”(Memories) “草稿本”是针对一个任务会话的,那如果Agent需要记住一些跨越很多次会话的信息呢?这就需要“长期记忆”了。
    比如,有些Agent会记录自己每次犯错的经历,然后反思一下自己为什么会犯错,把这些“教训”存起来。下次遇到类似的情况,它就能吸取教训,避免再犯同样的错误。
    你们平时用的ChatGPT就有点像这样,它能记住你的一些偏好,帮你生成更符合你要求的内容。这就有点像Agent有了自己的“成长日记”和“人生经验”。


绝招二:选上下文(Select Context)
既然我们把信息保存起来了,那下一步就是:怎么把需要的信息“精准”地选出来,塞到“工作记忆”里

  • 从“草稿本”里选 如果“草稿本”是一个文件,Agent可以直接去读它。如果是Agent内部的变量,开发者可以控制在什么时候把哪些信息暴露给Agent。
  • 从“长期记忆”里选 Agent可以根据当前的任务,去它的“长期记忆”里挑选有用的信息。比如:
    • 范例(Episodic Memories): Agent可以找一些之前做过的类似任务的成功范例,学习别人是怎么做的。
    • 指导(Procedural Memories): Agent可以回忆一下自己曾经定下的规则或者操作指南。
    • 事实(Semantic Memories): Agent可以找出一些和当前任务相关的知识点。
    不过,从一大堆记忆里准确地找出有用的信息,可不是一件容易的事。就像你在一个巨大的图书馆里找一本特定的书,需要好的分类和索引。现在很多Agent会用一些技术(比如“向量嵌入”和“知识图谱”)来帮助它们更精准地找到需要的记忆。
    但是,有时候也会发生“选错记忆”的尴尬事。比如ChatGPT有一次把用户的地址信息不小心加到了图片请求里,让用户感觉自己的隐私被泄露了。所以,“选”这一步,也是个技术活,需要非常小心。
  • 选择工具 Agent会用各种工具,但如果工具太多,工具说明又很相似,Agent就容易“犯选择困难症”。一个聪明的办法是,当Agent需要工具时,只把最相关的几个工具说明“选”出来,给Agent看。这就像你装修房子,工人会把最常用的几个工具放在手边,而不是把所有工具都摊在地上。
  • 选择知识(RAG) Agent要用到很多知识,比如编程的Agent,它需要查阅大量的代码库和文档。怎么从海量的代码里,快速找到它需要的代码片段或者函数说明呢?这又是一个“选”的问题。现在很多Agent会用RAG(Retrieval Augmented Generation,检索增强生成)技术,简单来说,就是先“检索”出最相关的知识,再交给Agent去理解和使用。这比让Agent自己去海量信息里“大海捞针”要高效得多。


绝招三:压上下文(Compressing Context)
如果信息太多,又不能直接丢掉,那怎么办?压缩!就像我们把大文件打包成ZIP格式一样。

  • 上下文摘要(Context Summarization) Agent在完成任务的过程中,会产生大量的对话记录和工具调用结果。如果这些信息一直累积,很快就会爆满。这时候,Agent可以把之前的一些对话或者工具结果进行“总结提炼”,只保留最关键的信息,扔掉那些不重要的细节。
    比如,你在用某个编程助手写代码,如果对话太长,它会自动把之前的对话“总结”一下,只留下关键的修改记录和你的最新要求。这就像你记笔记一样,把一整页的会议记录浓缩成几句话的要点。
    当然,总结提炼也很有挑战性,要保证总结出来的东西不漏掉重要信息,不歪曲原意。
  • 上下文裁剪(Context Trimming) 这是一种更粗暴但有效的方法。直接“剪掉”那些过时或者不重要的信息。比如,最简单的就是把很久以前的对话消息直接删除掉,只保留最近的。这就像你清理手机相册,把不重要的照片直接删掉,为新照片腾空间。


绝招四:隔上下文(Isolating Context)
有时候,与其把所有信息都塞到一个Agent的“工作记忆”里,不如把它“隔”开,让不同的Agent或者不同的部分处理不同的信息

  • 多Agent协作(Multi-agent) 想象一下,你有一个非常大的项目要完成,一个人肯定搞不定。这时候你会不会找几个小伙伴一起分工合作?Agent也是一样!
    可以把一个大任务分成好几个小任务,每个小任务交给一个子Agent去完成。每个子Agent只负责自己的那一小块,有自己的“工作记忆”,只关心和自己任务相关的信息。这样一来,每个子Agent的“工作记忆”就不会爆满,而且它们可以同时进行,大大提高了效率。
    当然,多Agent协作也有挑战,比如怎么协调它们的工作,怎么避免重复劳动等等。
  • 上下文隔离与环境(Context Isolation with Environments) 有些Agent在调用工具时,会产生大量的数据,比如图片、音频或者大段的计算结果。如果把这些都塞回Agent的“工作记忆”里,那肯定很快就爆了。
    一个巧妙的方法是,把这些大块的数据放在一个“独立的环境”里,就像一个沙盒(Sandbox)。Agent只需要知道这些数据在哪里,需要的时候再去“沙盒”里拿就行了。这样,Agent的“工作记忆”就只存放关键的指令和少量信息,而那些重量级的数据就被“隔离”在外面了。
  • 状态对象(State Object) Agent的运行过程中,会有一些需要长期保存的“状态”,比如用户的偏好设置、任务的进度等等。这些信息也可以放在一个状态对象里。这个状态对象就像一个专门的“抽屉”,里面分了很多小格子,每个小格子放不同的信息。Agent的“工作记忆”只和其中一两个小格子进行交互,其他的小格子里的信息就被“隔离”起来,只有在需要的时候才会被用到。

总结一下!
所以,Agent的“上下文工程”,就像是给Agent的大脑做一个精密的管理系统。它的核心就是四大绝招:

  • 写(Write):把重要的信息存起来,在“工作记忆”外面。
  • 选(Select):根据需要,把最合适的、最重要的信息挑出来,塞进“工作记忆”。
  • 压(Compress):把信息总结提炼,或者直接裁剪掉不重要的部分,减少“工作记忆”的负担。
  • 隔(Isolate):把任务拆分,或者把大块的数据隔离在外部,让Agent的“工作记忆”更专注。
掌握了这些“上下文工程”的技巧,我们就能开发出更聪明、更高效、更省钱的Agent!是不是很有意思?