多智能体系统的上下文工程——为上下文压缩构建 Summarizer 智能体

0 阅读44分钟

本章标志着一次重要转向:我们将直面企业级 AI 中最核心的业务挑战之一——如何管理大规模上下文所带来的财务成本与技术成本。我们将通过引入一种新的能力——上下文缩减(context reduction) ——来应对这一挑战,具体方式是增加一个名为 Summarizer(摘要器) 的专用智能体。它的职责,是对内容体量进行智能压缩,充当一道“守门员”,帮助系统应对 token 上限、API 成本等现实约束。

在真正写下第一行代码之前,我们会先回到系统的架构蓝图,从概念层面设计一种新的能力:主动式上下文管理(proactive context management) 。我们将可视化 Summarizer 如何集成到现有框架中。在方案明确之后,我们再进入实现阶段,把设计落到代码中,构建出一个自包含的智能体,并将其整合进引擎可发现的工具箱之中。

到本章结束时,你不仅会构建出一种新的上下文缩减型智能体,还会进一步深化你对“像一名上下文工程师那样思考”究竟意味着什么的理解。你将学会如何分析一个业务约束、如何为其设计高效的架构方案,以及如何将其实现到一个多智能体系统(MAS)中。这些能力,正是把一个 AI 从业者从“操作员”提升为“架构师”的关键:能够构建真正智能、达到企业级标准的系统。

本章将涵盖以下主题:

  • 设计玻璃盒系统(glass-box system)的架构
  • 使用 Summarizer 智能体实现上下文缩减
  • 将技术效率转化为业务价值

设计玻璃盒系统的架构

和前几章一样,在进入实现之前,我们仍然先从架构走查开始,以便先在视觉和概念层面建立清晰认知。为了适应这些新能力,我们必须越来越学会在写代码之前先思考 AI 系统。最先进的 AI Copilot 如今确实能够显著提升代码生成效率,但在没有人类先完成设计思考之前,它们依然无法独立完成系统设计。我们人类依然是架构师,而 AI Copilot 只是工人,如图所示:

image.png

图 6.1:从人类架构师到 AI 工人

带着这种架构师心态,我们必须面对每一位 AI 工程师都会遇到的一个关键选择。很多人急于把 AI 当成一个简单的黑盒:输入进去一些东西,然后寄希望于得到高质量输出。我们将采取一种更专业、更强大的方式:构建一个玻璃盒系统(glass-box system) ,也就是刻意为透明性与可控性而设计的系统。不同于内部逻辑被隐藏起来的黑盒,我们的 Context Engine 是一个“可被理解”的系统。

在第 4 章中,我们已经开始实现这种玻璃盒能力:通过详细的 ExecutionTrace,让每一个动作都可追踪。这样一来,每一个组件都是模块化的,AI 做出的每一个决策也都可以被检查。我们在构建内容缩减能力时,也会采取同样的原则。

你可能会想:“为什么要这么麻烦?”答案其实很简单。现在几乎所有人都在冲向聊天机器人,希望借助它们提升生产力。然而,AI Copilot 输出质量的高低,与我们输入质量的高低是严格相关的。因此,我们必须构建一个玻璃盒引擎,以便实现完全可控。第 5 章中强化过的 Context Engine,本质上已经是一套具有顺序化操作流的复杂系统。理解这种玻璃盒架构,是理解我们新的 Summarizer 智能体如何无缝融入现有逻辑的关键。

本节中,我们会先从引擎的运行流出发,走一遍从用户初始目标到最终生成结果的全过程。然后,我们再精确定位:新的组件究竟会在什么地方被引入,以及为什么要在这些地方引入。这样一种“双层展开”的方式,将让你完整看清:这台引擎是如何从一个强大的编排器,演化为一个具备效率意识的系统的。

下面,让我们开始设计内容缩减过程的架构蓝图。

分步骤架构走查

本次走查的向导是图 6.2。图中的每个节点都采用颜色编码,并与我们代码中对应的章节保持一致。本章新增的组件,都会被明确标注为 [NEW]

image.png

图 6.2:内容缩减架构

图 6.2 的图例为 Context Engine 的各个组件提供了颜色映射:

  • 蓝色(第 7 节) :用户最终运行的执行脚本
  • 白色(第 6 节) :引擎核心,包括主 orchestrator、planner 和 tracer
  • 紫色(第 5 节) :Agent Registry,即系统的工具箱
  • 绿色(第 4 节) :执行实际工作的专用智能体
  • 橙色(第 3 节) :提供通用能力的辅助函数

光是看这张流程图,可能就已经让人有点发怵了!脑海里最先冒出来的念头可能是:“这到底什么时候才到头?”我们已经走过了五章,没错,事情的确越来越复杂了。但这恰恰就是关键所在。一个 AI 架构师,也就是一名上下文工程师,本质上就是一个复杂性思考者(complexity thinker)

很多人会觉得,从零开始搭系统不值得,于是急着投向那些现成平台,幻想凭借一些光鲜的 demo 就能轻松落地。但现实远没有那么浪漫。任何高级 AI 项目,无一例外,都会撞上硬墙。有时候是数据缺失,项目推进被迫停住;有时候是关键函数行为不符合预期;还有些时候,bug 总会在最糟糕的时刻冒出来。

那这种时候怎么办?这时,真正的 AI 工程师才会站出来——那个真正理解系统架构底层逻辑的人,那个知道基于 MAS 或 MCP 的 Context Engine 在最低层是如何运转的人。到那个时刻,所有人都会去找专家,而不是去找那个还站在仪表盘前一脸茫然、不知道哪里出错了的操作员。

既然我们已经看过了完整蓝图,现在就让它真正“动”起来。图 6.2 会在我们沿着一项任务的真实路径走一遍之后变得鲜活起来:从用户输入,到最终输出,整个过程分为以下四个运行阶段。理解这条流转路径之后,你就会更容易看清新的 Summarizer 智能体究竟位于哪里,以及它是如何增强引擎能力的:

启动(Initiation)

一切始于用户运行最终代码块。context_engine() 函数是整个系统的入口,也是 orchestrator 的核心,它从这里开始接管整个流程。正如前几章已经反复建立起来的认知一样:这里正是把“意图”转化为“动作”的地方。

规划(Planning)

一旦进入 context_engine(),第一优先级就是制定行动计划。首先会创建一个 ExecutionTrace 对象,它充当引擎的“飞行记录仪(flight recorder)”,记录每一步动作,以便实现透明性与调试能力。随后,planner() 需要上下文——它会通过 get_capabilities_description() 查询 AgentRegistry,以了解当前有哪些专用智能体可用。有了这份清单,再结合用户目标,planner 会通过 call_llm_robust() 调用 LLM,生成一份结构化的、多步骤 JSON 计划,用来定义整体策略。

执行循环(Execution Loop)

一旦计划清晰,引擎就切换到执行模式。它会逐步遍历计划中的每一个步骤,通过 get_handler() 从 registry 中获取对应的智能体函数。接着,通过 resolve_dependencies() 解析依赖关系,也就是执行上下文链式传递:把类似 $$STEP_1_OUTPUT$$ 这样的占位符,替换成前面步骤真实产生的输出。然后,准备就绪的智能体被真正调用,以执行自己的任务,并且通常会依赖 query_pinecone()call_llm_robust() 这样的辅助函数完成数据检索或推理。每一步完成之后,其结果会被写入 trace 中,然后引擎无缝切换到下一步。

收尾(Finalization)

当所有步骤都执行完毕之后,引擎会通过在 trace 对象上调用 finalize() 来完成整个过程。它会记录最终状态和执行时间,然后把清晰、结构化的输出返回给用户。

我们的 Context Engine 现在已经像一支真正协同工作的智能团队那样运作起来:自主、agent-driven。每个组件都承担着明确职责,就像一支配合默契的团队成员一样。接下来,让我们进一步看看这些职责是如何被分配的,以及在系统复杂度增长时,它是如何维持平衡的。

职责分离

下面这条顺序化流程清楚展示了职责分离。每一个模块都沿用了图 6.2 中相同的颜色标签,方便你在视觉上把这里的概念与架构图中的位置对应起来。也正是在这个模块化框架之内,我们才会引入本章的新组件与升级:

  • 引擎核心(白色) 是大脑。它负责管理整个过程,但本身不直接做具体工作。它的逻辑是通用且稳健的,因此本章不需要修改。
  • 专用智能体(绿色) 是工人。每一个都负责系统中的某一项具体任务。我们将引入一个新的智能体(在图 6.2 中标为 [NEW AGENT] ),即 agent_summarizer。它的角色是智能守门员:接收大体量文本,并根据特定目标将其压缩成核心要点。这个智能体直接回应了 API 成本管理和固定 token 上限这两个业务需求。
  • Agent Registry(紫色) 是工具箱。它向 Planner 提供一份可读的工具说明书。我们会更新这份说明书(get_capabilities_description),加入新的 Summarizer 智能体,从而让 Planner 立刻获知这一新能力。
  • 辅助函数(橙色) 是共享工具,是那些默默支撑整个系统运行的“安静使能者”。我们会正式引入一个新的工具函数(在图 6.2 中标为 [NEW UTILITY] ),即 count_tokens。这个函数相当于引擎的“油量表”,让任何组件都能在把文本发送给 LLM 之前,先测量它的 token 成本。它是构建主动式、成本敏感型设计的基础工具。

现在我们已经理解了基础架构,以及新的组件会嵌入到哪里,接下来就要把这些变化所带来的战略影响总结出来,并且要做到:不论是技术人员还是非技术干系人都能看懂。作为上下文工程师,我们不能只会构建功能系统,还必须学会用决策者能理解的语言来解释系统演化。任何一次升级,不论多么技术化,都应当能够被转译成概念层面的表达,架起工程逻辑与业务价值之间的桥梁:

  • 阶段 1 和阶段 2 —— 主动式上下文管理(Proactive Context Management) :我们最核心的升级,并不只是多了一个新智能体,而是多了一种新的战略能力:主动式上下文管理。引擎不再只是被动处理输入给它的信息,而是可以先对其进行分析、测量和压缩。count_tokens 提供了测量能力,Summarizer 提供了执行能力。这使得引擎从一个纯粹反应式系统,变成了一个能够在更经济前提下解决更大问题的高效系统。
  • 阶段 3 —— 集成与可扩展性(Integration and Scalability) :我们架构最强大的地方在于:这样一个显著的新能力,居然可以在不重设计核心引擎的情况下被加入进来。我们只需增加 Summarizer 智能体,并更新 Agent Registry 的描述,Planner 就会自动学会如何使用这个新工具。这证明了系统具备高度可扩展性:未来要加入更多智能体与能力,也可以用极低的扰动实现,就像往一个井然有序的工作坊里再添一件新工具一样。
  • 阶段 4 和阶段 5 —— 验证(Validation) :最后一部分工作,就是证明这些升级真正生效了,而且同样重要的是:它们没有破坏任何既有功能。我们将进行严格测试,包括向后兼容性检查,以验证引擎仍然稳定,Planner 在处理简单场景时仍能正确生成计划。这种对验证的重视,是构建企业级可信系统的基础。

到这里,我们已经完成了不少架构层面的思考。但我们还必须能清楚解释:为什么“验证”对于一个面向企业使用的系统来说,是建立信任的关键。

为什么玻璃盒如此重要

正如流程图所展示的那样,这种清晰的职责分离,并不只是一个优雅的设计选择;同样,对这些升级进行概念层面梳理,也绝不是那种“可以在赶代码之前略过不看的铺垫内容”。它其实是任何严肃 AI 工程项目中的一种战略性要求(strategic imperative)

既然 AI Copilot 正在越来越多地承担“写代码”这件事,我们为什么还要急着奔向代码本身呢?最新、最强的 LLM 确实已经能够产出相当不错的生产级代码。所以,在进入代码之前,请先给自己一点时间,理解我们正在构建的这种玻璃盒架构,为什么会把你带向更高阶的 AI 专业能力。

首先,也是最重要的一点,这种设计可以主动防止技术债务。在一个高度耦合或单体化的系统中,增加一个新能力,通常意味着要对核心逻辑做复杂而高风险的修改。时间一长,整个系统就会变成一座“脆弱的纸牌屋(house of cards)”,任何一次改动都可能引发连锁崩塌。我们的架构则相反:它把智能体当作即插即用模块。新增 Summarizer,并不需要修改 Executor 或 Planner 的根本工作方式。这就像升级一辆车的 GPS ——你可以更换导航模块,却不需要重新设计发动机。这个原则,保证了我们的 Context Engine 在未来很多年里都能保持敏捷与可演化。

进一步说,这种模块化本身也是高效协作与扩展能力的前提。设想一个场景:一家企业希望分别为法务、财务和市场部门部署不同的智能体。基于我们的架构,三个独立开发者或团队可以并行开发 agent_legal_parseragent_financial_analyzeragent_marketing_writer。他们唯一需要遵守的约束,就是通过 MCP 进行通信,并把完成的智能体注册到中央 Agent Registry 中。他们并不需要理解引擎核心编排逻辑的复杂细节,这会显著降低参与门槛,加快新业务能力的开发速度。你实际上是在带领你的团队走向一个全新的时代。

image.png

图 6.3:从脆弱型 AI 系统走向敏捷型 AI 系统

图 6.3 所展示的,是你作为一名新兴的上下文工程架构师,正经历的一次重大转变——它区别于过去传统的 prompt 工程,也区别于经典 AI 系统设计。这种视觉隐喻远不只是两种软件设计模式之间的选择,它实际上代表着一种根本性的范式转移,而且这种转移对系统本身、也对人本身,都有深远影响。

对于 AI 系统而言,这意味着它从一个静态的、单一用途工具,进化成了一个具备韧性的、可生长的生态系统。它的价值,不再只取决于眼前一次输出是否有用,而更多取决于它是否具备随着时间推移不断适应、增长并整合新能力而不崩溃的能力。

对于人类工程师而言,这种转变更为重要。它把工程师的角色,从“构建孤立应用的人”提升为“设计智能系统的人”。随着 AI Copilot 越来越多地承担代码生成工作,人类最重要的技能,将变成战略前瞻性(strategic foresight) :设计那些不仅今天强大,而且足够敏捷、足以拥抱明日不可避免技术演进的框架。正是这种“为变化而设计”的敏捷方法,构成了现代上下文工程的真正本质。

有了这张清晰的架构与概念地图,我们现在已经准备好进入真正的动手实现。

使用 Summarizer 智能体实现上下文缩减

在充分理解了升级后引擎架构的基础上,我们已经为构建这一新能力打好了坚实地基。现在,我们将从架构理论转向实际实现。这个实现过程将是一个系统化、循序渐进的过程,需要对核心库文件做精确的增量修改,以便把这个新智能体无缝整合进系统之中。

本章中,用于编排和测试这些增强能力的主要工作空间,是专门的 notebook:Context_Engine_Content_Reduction.ipynb。它是第 5 章中 Context_Engine_Pre_Production.ipynb 的升级版。依赖安装部分保持不变。为了在引擎不断演化的过程中保持版本清晰、项目结构整洁,现在每一章的代码都放在自己的子目录中。对于本章来说,所有共享库文件都来自 commons/ch6/,这是一个清晰、有组织的空间,便于随着 Context Engine 的扩展持续管理升级。

本次升级将分为五个有序阶段,并建立在第 5 章中已经确立的稳健架构之上:

  • 阶段 1 —— 成本管理的基础(Foundation for Cost Management) :首先验证 count_tokens 工具函数,以便系统具备主动测量和管理上下文大小的能力。
  • 阶段 2 —— 构建 Summarizer 智能体(Building the Summarizer Agent) :在 agents.py 中构建新智能体的核心逻辑,将其设计为一个自包含、依赖可感知的模块。
  • 阶段 3 —— 将智能体集成进引擎工具箱(Integrating the Agent into the Engine Toolkit) :更新 registry.py,让 Planner LLM 获知这一新能力,并能够在工作流中动态使用摘要化。
  • 阶段 4 —— 强化 Writer 智能体(Reinforcing the Writer Agent) :升级 agent_writer,使其既能接收来自 Researcher 的输出({"facts": ...}),也能接收来自新 Summarizer 的输出({"summary": ...})。
  • 阶段 5 —— 演示这一新能力(Demonstrating the New Capability) :执行一个新的复杂目标,展示 Summarizer 智能体如何在真实场景中智能优化性能并降低成本。

我们的第一步,就是先来看成本管理。

成本管理的基础

本章的工作核心,是管理上下文大小,而这首先要求我们能够准确测量上下文大小。因此,我们会先验证 count_tokens 这个工具函数。它是在最初强化阶段加入到 helpers.py 库中的。

正如前面提到的,这个工具函数就像引擎的“油量表”,它能在文本被发送给 LLM 之前,精确测量它会消耗多少 token。这个函数看似简单,但却至关重要,因为它为后续所有成本管理策略奠定了基础。现在,我们来看它的实现:

# FILE: commons/helpers.py (existing code)
# This function is our primary tool for proactive token management.

def count_tokens(text, model="gpt-4"):
    """Counts the number of tokens in a text string for a given model."""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        # Fallback for models that might not be in the tiktoken registry
        encoding = tiktoken.get_encoding("cl100k_base")
    return len(encoding.encode(text))

count_tokens 函数接收一个文本字符串,以及一个可选的模型名称。它使用 tiktoken 库——也就是 OpenAI 官方的 tokenizer——把文本编码成一个 token 整数列表,然后返回这个列表的长度。通过把编码过程包裹在 try...except 中,它还能优雅处理某些模型名称不在 tiktoken 注册表中的情况,并自动退回到一个通用的基础编码方式,从而保证函数无论如何都会返回一个有效值。

既然我们的基础测量工具已经验证完成,现在就可以开始构建那个真正会利用这项原则来管理上下文的智能体了。接下来,我们进入 Summarizer 智能体的构建。

构建 Summarizer 智能体

Summarizer 智能体,是我们针对“上下文过长”问题的解决方案。它的职责,是把大段文本智能压缩为面向特定目标的简洁摘要,从而确保只有最相关的信息才会被传递给工作流中的后续智能体。

我们会把这个新智能体加入 agents.py 文件,并沿用之前为其他智能体建立的生产级模式。它将是一个自包含函数,所有依赖都通过参数传入,并通过 MCP 返回结果。它真正的智能性,体现在它会利用 summary_objective ——这个目标会引导 LLM 生成的摘要不仅更短,而且更有用

这个函数首先定义自己的签名 agent_summarizer,接收标准的 mcp_message,以及它所需的依赖:用于 API 调用的 client 对象,以及 generation_model 配置。进入 try 代码块之后,它会从 MCP 消息内容中拆出两个必要输入:

  • text_to_summarize:待摘要的大段文本
  • summary_objective:用于说明“摘要应当围绕什么目标来缩减”的明确意图
# FILE: commons/ch6/agents.py
# This new function is added to our existing agent library.
# It follows the established dependency injection and structured logging patterns.

def agent_summarizer(mcp_message, client, generation_model):
    """
    Reduces a large text to a concise summary based on an objective.
    Acts as a gatekeeper to manage token counts and costs.
    """
    logging.info("[Summarizer] Activated. Reducing context...")
    try:
        # Unpack the inputs from the MCP message
        text_to_summarize = mcp_message['content'].get('text_to_summarize')
        summary_objective = mcp_message['content'].get('summary_objective')

该智能体包含一个输入校验步骤,以确保两个必要输入都存在;如果缺失,它就会抛出 ValueError。随后,它会构造一个 system_prompt,要求 LLM 扮演一名专家级摘要 AI。user_prompt 则通过 f-string 拼接而成,并清晰标出 OBJECTIVETEXT TO SUMMARIZE。这种结构化提示设计,对引导 LLM 生成高质量、与目标强相关的摘要至关重要:

# The agent validates that it has received the necessary inputs before proceeding.

        if not text_to_summarize or not summary_objective:
            raise ValueError("Summarizer requires 'text_to_summarize' and 'summary_objective' in the input content.")

        # Define the prompts for the LLM
        system_prompt = """You are an expert summarization AI. Your task is to reduce the provided text to its essential points, guided by the user's specific objective. The summary must be concise, accurate, and directly address the stated goal."""
        user_prompt = f"""--- OBJECTIVE ---\n{summary_objective}\n\n--- TEXT TO SUMMARIZE ---\n{text_to_summarize}\n--- END TEXT ---\n\nGenerate the summary now."""

最后,该智能体会调用我们已经强化过的 call_llm_robust 辅助函数,把 prompt 和通过依赖注入传入的配置一起交给它。得到的摘要结果,再通过 create_mcp_message 封装成标准 MCP 消息。输出是一个带有 "summary" key 的字典,以保证下游智能体能够依赖一致、可预测的数据结构。整个过程同样被包裹在 try...except 中,以实现稳健的错误处理:

# The agent calls the robust LLM helper function and returns the result.

        # Call the hardened LLM helper to perform the summarization
        summary = call_llm_robust(
            system_prompt,
            user_prompt,
            client=client,
            generation_model=generation_model
        )

        # Return the summary in the standard MCP format
        return create_mcp_message("Summarizer", {"summary": summary})
    except Exception as e:
        logging.error(f"[Summarizer] An error occurred: {e}")
        raise e

让我们先停一下,回过头看一眼。我们之所以能够如此平滑地整合一个新智能体,是因为我们做对了几件事:校验输入、用清晰目标引导 LLM、返回结构稳定的 MCP 消息,并用 try...except 把调用包裹起来。这就是良好上下文工程的样子。

微型上下文工程(Micro-context engineering)

虽然 Summarizer 智能体的 Python 代码本身并不复杂,但它真正的威力,并不在于这个函数本身,而在于我们赋予 summary_objective 的上下文质量。精确地设计这个 objective,本身就是一个非常典型的**微型上下文工程(micro-context engineering)**案例。

所谓微型上下文工程,就是把一个通用、多用途的工具,转变为一个面向特定任务的高精度专用工具的能力。LLM 和任何强大工具一样,只有在被给予清晰、无歧义指令时,才能发挥最佳效果。

一个优秀的上下文工程师,会提供扎实、目标明确的输入;一个糟糕的上下文工程师,则永远得不到自己期待的结果。所以,请务必睁大眼睛,真正去提升你的上下文设计能力。务必要意识到:instruction 并不等同于那种老式 prompt。看看“一个模糊目标”与“一个经过架构设计的目标”之间,会带来多么巨大的输出质量差异。

一个糟糕的目标,通常是模糊而开放的:

“Summarize this text.”

这会迫使 LLM 去猜测“用户到底认为什么重要”。结果往往是一段通用、平庸的摘要,甚至可能完全错过用户真正关心的信息,既浪费 API 调用,又浪费用户时间。

而一个强目标(strong objective),则是一份微型语义蓝图(miniature semantic blueprint) 。它具体、带约束,并且清晰规定了所需输出:

“Extract the names of all involved parties, the key financial figures discussed, and the final resolution date from the following legal document. Exclude all procedural boilerplate and present the output as a JSON object.”

这个目标会把原本通用的 Summarizer,转变为一个专门面向当前任务的高精度实体抽取工具。它不给歧义留下空间,并且几乎保证了输出会是有用而且结构化的。掌握这种目标设计能力,是上下文工程师的核心竞争力,因为它使得一个单一、可复用的智能体,能够被动态地重定向去承担大量具体、高价值的业务任务。

我们再次看到了那种从“开发”走向“设计”的范式转移。我们不会被 AI 取代。只要我们是优秀的上下文工程师,就能够通过持续升级自己,把 AI 工人带到更高层次。那些糟糕的 AI 工程师,只会产出低价值输出,如图 6.4 所示。

image.png

图 6.4:上下文工程技能的重要性

现在,Summarizer 智能体已经构建完成,但它仍然是孤立存在的。接下来,我们必须更新引擎的中央工具箱,让这一新能力变得可发现。

将新智能体集成进引擎工具箱

随着 Summarizer 智能体已经被独立构建并测试通过,下一步就是让整个系统能够发现它。一个 Planner 根本不知道存在的智能体,是永远不可能被用到的。

AgentRegistry 就是整个 Context Engine 的可发现工具箱。为了完成这次升级,我们必须把新的 Summarizer 智能体加入其中。

这一过程需要对 registry.py 文件做两项精确修改:

  • agent_summarizer 函数加入 registry 内部字典
  • 更新 get_capabilities_description() 方法,也就是 Planner 会读取的那份纯文本“工具说明书”,让它知道现在多了什么工具,以及该如何使用它们

第二步尤其关键,因为它让系统具备了动态规划能力:Planner 不需要被硬编码地教会新能力,而是只要通过读取说明文本,就能学会怎么使用新工具。

AgentRegistry 类的 __init__ 方法中,我们把新的 key-value 对加入 self.registry 字典。key 是智能体名称 "Summarizer",它会在执行计划中被使用;value 则是我们刚才创建的可调用函数 agents.agent_summarizer

# FILE: commons/ch6/registry.py
# The entire file is updated to integrate the new agent.

# === Imports ===
import logging
import agents
from helpers import create_mcp_message

# === 5. The Agent Registry (Final Hardened Version) ===
class AgentRegistry:
    def __init__(self):
        self.registry = {
            "Librarian": agents.agent_context_librarian,
            "Researcher": agents.agent_researcher,
            "Writer": agents.agent_writer,
            # --- NEW: Add the Summarizer Agent ---
            "Summarizer": agents.agent_summarizer,
        }

接下来,我们在 get_handler 方法中加入一个新的 elif 分支。这样一来,当 Executor 请求 "Summarizer" 时,registry 就能够正确地为它准备好 clientgeneration_model 这些依赖,从而保证它能正常工作。这也严格遵循了我们一贯坚持的依赖注入模式:

# The get_handler method is updated to prepare the new agent with its dependencies.

    def get_handler(
        self, agent_name, client, index, generation_model,
        embedding_model, namespace_context, namespace_knowledge
    ):
        handler_func = self.registry.get(agent_name)
        if not handler_func:
            logging.error(f"Agent '{agent_name}' not found in registry.")
            raise ValueError(f"Agent '{agent_name}' not found in registry.")

        # --- UPDATED: Add a condition for the Summarizer ---
        if agent_name == "Librarian":
            return lambda mcp_message: handler_func(
                mcp_message, client=client, index=index,
                embedding_model=embedding_model,
                namespace_context=namespace_context
            )
        elif agent_name == "Researcher":
            return lambda mcp_message: handler_func(
                mcp_message, client=client, index=index,
                generation_model=generation_model,
                embedding_model=embedding_model,
                namespace_knowledge=namespace_knowledge
            )
        elif agent_name == "Writer":
            return lambda mcp_message: handler_func(
                mcp_message, client=client,
                generation_model=generation_model
            )
        elif agent_name == "Summarizer":
            return lambda mcp_message: handler_func(
                mcp_message, client=client,
                generation_model=generation_model
            )
        else:
            return handler_func

最后,也是最关键的更新,是对 get_capabilities_description 返回的说明文本进行修改。我们为 Summarizer 新增一条描述,清晰定义它的角色、输入("text_to_summarize""summary_objective"),以及输出格式。正是这段详细描述,让 Planner 能够理解:何时应该战略性地调用 Summarizer,以及该如何调用它

# Finally, we update the capabilities description that the Planner LLM reads.

    def get_capabilities_description(self):
        """Returns a structured description of the agents for the Planner LLM."""
        # --- UPDATED: Add the Summarizer's capabilities ---
        return """
Available Agents and their required inputs.
CRITICAL: You MUST use the exact input key names provided for each agent.

1. AGENT: Librarian
   ROLE: Retrieves Semantic Blueprints (style/structure instructions).
   INPUTS:
     - "intent_query": (String) A descriptive phrase of the desired style.
   OUTPUT: The blueprint structure (JSON string).

2. AGENT: Researcher
   ROLE: Retrieves and synthesizes factual information on a topic.
   INPUTS:
     - "topic_query": (String) The subject matter to research.
   OUTPUT: Synthesized facts (String).

3. AGENT: Summarizer
   ROLE: Reduces large text to a concise summary based on a specific objective. Ideal for managing token counts before a generation step.
   INPUTS:
     - "text_to_summarize": (String/Reference) The long text to be summarized.
     - "summary_objective": (String) A clear goal for the summary (e.g., "Extract key technical specifications").
   OUTPUT: A dictionary containing the summary: {"summary": "..."}.

4. AGENT: Writer
   ROLE: Generates or rewrites content by applying a Blueprint to source material.
   INPUTS:
     - "blueprint": (String/Reference) The style instructions (usually from Librarian).
     - "facts": (String/Reference) Factual information (usually from Researcher or Summarizer).
     - "previous_content": (String/Reference) Existing text for rewriting.
   OUTPUT: The final generated text (String).
"""

图 6.5 展示了这种动态、四步式发现过程,它使 Planner LLM 能够学会识别并战略性使用新的智能体:

image.png

图 6.5:Planner 与 AgentRegistry 之间的动态发现回路

这张图展示了 get_capabilities_description() 方法如何成为 Planner 与 AgentRegistry 之间的桥梁。流程开始于 Planner(大脑)向 Agent Registry(工具箱)询问:当前系统中有哪些工具可用(1)。Registry 的回应并不是代码,而是一份清晰、纯文本形式的说明手册,描述每个智能体的职责与输入(2)。通过阅读这份说明,Planner 便会发现所有可用智能体,包括新加入的 Summarizer(3)。有了这份知识,Planner 就能够制定出一份知情、合理的多步骤计划,在正确的时机使用正确的工具来完成用户目标(4)。正是这种 Planner 通过 registry 动态学习的解耦式发现回路,使系统具备了可扩展性、适应性与真正的智能性。

到这里,我们的新智能体已经被完整集成进 Context Engine 的整体架构。接下来,让我们进一步强化 Writer,使其具备更高的灵活性。

强化 Writer 智能体以获得更高灵活性

现在,新的 Summarizer 智能体已经完全接入系统工具箱。不过,稳健系统设计的一个核心原则,是确保新组件能够和旧组件有效协同。Summarizer 的引入,意味着 Writer 现在多了一个可能的数据来源,而它之前只被设计成能和 Researcher 协作。为了让引擎真正具备动态性,我们必须升级 Writer,让它更具适应性,从而能够无缝接收来自两个潜在协作者中的任意一个的输入。

这次升级体现了高级系统设计中的一个核心思想:构建的组件不仅自身要强大,而且在交互层面也必须足够灵活。现在,我们将强化 Writer,使其能够处理多种数据格式,从而让整个 MAS 变得更稳健、更智能。

数据契约问题(The data contract challenge)

这一升级需求,是在最初测试中暴露出来的。Planner 在其“涌现式智慧”下,已经能够正确地把新 Summarizer 的输出链到 Writer 上。然而,这也引发了一次数据契约违约(data contract violation) 。因为这两个提供信息的智能体,其输出格式稍有差异:

  • Researcher 输出{'facts': '...'}
  • Summarizer 输出{'summary': '...'}

原版 Writer 只会理解第一种 schema。当它收到的是带 'summary' key 的字典,而不是 'facts' key 的字典时,它就失败了。为了解决这个问题,我们要让 Writer 变成“双语的(bilingual) ”,也就是说,它能够理解这两种数据格式。

我们现在会修改 commons/ch6/agents.pyagent_writer 函数开头的那段数据拆包逻辑。这一升级本身非常简单,但威力很大——它教会了 Writer 去检查多种可能的输入 key。

下面是强化版 agent_writer 的完整代码:

# FILE: commons/ch6/agents.py (UPGRADED agent_writer)

def agent_writer(mcp_message, client, generation_model):
    """Combines research with a blueprint to generate the final output."""
    logging.info("[Writer] Activated. Applying blueprint to source material...")
    try:
        blueprint_data = mcp_message['content'].get('blueprint')
        facts_data = mcp_message['content'].get('facts')
        previous_content = mcp_message['content'].get('previous_content')

函数签名,以及对 MCP 主体内容(blueprintfactsprevious_content)的初步拆包,和之前保持一致:

        # UPGRADE: Robust logic for handling multiple data contracts
        blueprint_json_string = blueprint_data.get('blueprint_json')
            if isinstance(blueprint_data, dict) else blueprint_data

        facts = None
        if isinstance(facts_data, dict):
            # First, try to get 'facts' (from Researcher)
            facts = facts_data.get('facts')
            # If that fails, try to get 'summary' (from Summarizer)
            if facts is None:
                facts = facts_data.get('summary')
        elif isinstance(facts_data, str):
            facts = facts_data

        if not blueprint_json_string or (not facts and not previous_content):
            raise ValueError("Writer requires a blueprint and either 'facts' or 'previous_content'.")

这段代码中包含了关键升级。提取出 blueprint_json_string 之后,我们加入了新的逻辑来寻找事实内容。代码首先检查收到的 facts_data 是否是一个字典。如果是,它会先尝试读取 'facts' key;如果返回的是 None,则会立刻再尝试 'summary' key。正是这一小段条件判断,让 Writer 立刻兼容了来自 Researcher 和 Summarizer 两种不同来源的输出。

        # Determine the source material and label for the prompt
        if facts:
            source_material = facts
            source_label = "SOURCE FACTS"
        else:
            source_material = previous_content
            source_label = "PREVIOUS CONTENT (For Rewriting)"

        # Construct the prompts and call the LLM...
        system_prompt = f"""You are an expert content generation AI...""" # (prompt remains the same)
        user_prompt = f"""--- SOURCE MATERIAL ({source_label}) ---\n{source_material}\n--- END SOURCE MATERIAL ---\n\nGenerate the content now...""" # (prompt remains the same)

        final_output = call_ll_robust(
            system_prompt, user_prompt, client=client,
            generation_model=generation_model
        )
        return create_mcp_message("Writer", final_output)
     
    except Exception as e:
        logging.error(f"[Writer] An error occurred: {e}")
        raise e

函数其余部分与之前相同:它会决定应该使用哪个数据作为 source_material,然后构造详细的 system prompt 和 user prompt,并调用 LLM 来生成最终内容。

现在,Writer 已经被强化得足以处理多种数据来源。于是,我们终于可以开始对新的上下文缩减工作流进行第一次端到端测试了。

观察 Summarizer 在实战中的表现

本章实现阶段的最后一步,就是展示新的上下文缩减工作流。我们要设计一个目标,使得 Summarizer 的使用不仅“有帮助”,而且是“成功完成任务所必需”的。

由于 LLM 是随机性模型,因此,不同运行之间输出可能会有所变化。

这个目标将包含两个层次:它首先会明确要求引擎对一大段给定文本进行摘要,并且围绕特定目标来提炼;随后,又要求引擎把这份摘要作为事实基础,去完成一个创意写作任务。这样的复杂结构,会强迫 Planner 生成一个多步骤计划,并通过上下文链式传递,把 Summarizer 的输出作为 Writer 的输入。这个测试将成为决定性证据,证明我们的新智能体已经被完整集成,并且引擎能够动态地调度它。

首先,我们定义一个字符串变量 large_text_from_researcher,其中包含一段关于木星探测器 Juno 的高密度技术说明文本。然后,我们使用 f-string 构造目标,明确要求引擎按顺序完成两件事:先为一个特定目标摘要这段文本,再利用摘要结果去完成一个创意写作任务。

# FILE: Context_Engine_Content_Reduction.ipynb
# This is the final demonstration from the main notebook's control deck.

# 1. Define a large piece of text that would be expensive or too long
# to use as direct context for the Writer agent.
large_text_from_researcher = """
Juno is a NASA space probe orbiting the planet Jupiter. It was launched from Cape Canaveral Air Force Station on August 5, 2011, as part of the New Frontiers program...
"""

# 2. Define a goal that requires both using the large text AND a creative step.
goal = f"""First, summarize the following text about the Juno probe to extract only the key facts about its scientific mission and instruments. Then, using that summary, write a short, suspenseful scene for a children's story about the probe's dangerous arrival at Jupiter.

--- TEXT TO USE ---
{large_text_from_researcher}
"""

我们继续沿用之前运行时相同的 config 字典,并将所需组件传给 execute_and_display 函数:

# The configuration remains the same, and the execution call is made.

# 3. Use the same configuration dictionary
config = {
    "index_name": 'genai-mas-mcp-ch3',
    "generation_model": "gpt-5",
    "embedding_model": "text-embedding-3-small",
    "namespace_context": 'ContextLibrary',
    "namespace_knowledge": 'KnowledgeStore'
}

# 4. Call the execution function
execute_and_display(goal, config, client, pc)

运行这个单元格之后,我们就可以通过输出中的 TECHNICAL TRACE 来拆解引擎的思维过程。trace 会揭示出一个多步骤计划,其第一步正是调用 Summarizer 智能体,把那段冗长文本成功压缩成一份简洁、要点式的事实摘要。更关键的是,trace 会清楚显示:第一步产生的输出,随后通过上下文链式传递,被当作 facts 输入传给了后续的 Writer。最终输出是一篇创意故事,而它的事实基础来自摘要结果,而不是原始大段文本。这就证明:我们的上下文缩减工作流已经被成功执行。它也确认了 Summarizer 已经成为 MAS 中一个完整可用、而且具有战略价值的新成员。

接下来,让我们进一步检查最终输出,确认这一实现确实按预期工作。

拆解引擎的思维过程:证据就在 Trace 中

最终生成的文本当然很吸引人,但真正衡量我们成功与否的,是 TECHNICAL TRACE。作为引擎的“飞行记录仪”,trace 会以透明、逐步的方式呈现整个推理与行动过程。通过拆解它,我们就能精确看清:Planner 是如何为了满足这个复杂目标而制定出一套全新策略的;同时,也能看到 Summarizer 智能体在其中扮演了怎样的关键角色。

下面,我们将逐步走查这次测试运行中的执行 trace,分析每一个决策与动作,以确认这个以效率为中心的新架构,的确是按照设计预期运转的。

第 1 步:Summarizer 智能体率先登场

Executor 执行的第一件事,就是调用 Summarizer 智能体。这一点,是我们这次升级最重要的验证信号。

Planner 在面对用户目标时,分析出了两个关键元素:

  • 目标中嵌入了一大段文本
  • 用户明确要求“对下面的文本做摘要”

基于我们在 registry.py 中更新过的 capabilities description,Planner 正确判断:Summarizer 才是最适合承担第一步的工具。它并没有默认走向 Researcher,因为事实上下文其实已经直接包含在用户目标之中了。这清楚地展示了**动态规划(dynamic planning)**的能力。

Planner 还非常聪明地从用户请求中抽取出了一条高度具体的摘要目标:

'summary_objective': 'Extract only the key facts about '
                     "Juno's scientific mission and its "
                     'instruments/power system...'

随后,Summarizer 智能体真正执行任务,通过这一上下文与目标调用 LLM。它的输出是一份精炼的项目符号式摘要,只保留了与 Juno 任务最相关的核心事实:

'output': { 'summary': '- Operates in a polar orbit around Jupiter...'
                       '- Measures Jupiter’s composition, gravitational field...'
                       '- Investigates formation by probing the interior...'
                       '- Determines the amount of water in the deep atmosphere...'
                       '- Maps mass distribution and characterizes deep winds...'
                       '- Powered and stabilized by three very large solar-array wings...'
          }

在这里,我们可以直接看到这个智能体带来的经济与技术价值。只要借助 count_tokens 工具函数,我们就能定量衡量压缩效果:

  • 原始文本(text_to_summarize):253 tokens
  • 最终摘要(output):110 tokens

Summarizer 实现了 56.5% 的 token 压缩率。它成功过滤掉了那些高体量、低相关性的细节(例如发射日期、与 Galileo 轨道器的比较等),只把低体量、高相关性的摘要传递给下游更昂贵的生成步骤。这一动作,直接转化为更低的 API 成本,也能确保最关键的信息在后续阶段被保留下来。

在实际开发中,Context Engine 有很多地方都可以插入 token 统计逻辑,至于把它放在哪里、以什么方式统计,往往需要在开发期的架构 workshop 中共同决定。例如,在这个案例中,你也可以把 token 统计写成一个后执行函数:

# === Post-Execution Analysis: Quantifying Context Reduction ===

# Make sure to import the count_tokens utility
from helpers import count_tokens

# 1. Get the original text that was sent to the Summarizer
#    (This is the same variable we defined in the control deck)
original_text = large_text_from_researcher

# 2. Get the summarized text from the trace object
#    The trace object 'trace_1' was returned by the execute_and_display function.
#    We look inside the first step (index 0) of the execution trace.
summarized_text = trace_1.steps[0]['output']['summary']

# 3. Use the 'count_tokens' utility to measure both
original_tokens = count_tokens(original_text)
summarized_tokens = count_tokens(summarized_text)
reduction_percentage = (1 - (summarized_tokens / original_tokens)) * 100

# 4. Print the results
print("--- Context Reduction Analysis ---")
print(f"Original Text Tokens: {original_tokens}")
print(f"Summarized Text Tokens: {summarized_tokens}")
print(f"Token Reduction: {reduction_percentage:.1f}%")

这样的后执行函数,只是你可以根据项目需要构建的许多函数之一。

现在,我们继续进入第 2 步,看看 Librarian 智能体是如何接力的。

第 2 步:Librarian 获取风格蓝图

既然故事所需的事实基础已经被提炼并压缩完毕,引擎接下来就要处理用户目标中的第二部分:创意写作任务。Planner 判断,要想满足“写一个适合儿童故事、短小且充满悬念的场景”这一要求,它就必须先获得一个风格指导。

于是,Executor 会调用 Librarian,并传入一个 intent_query,内容大致是 “short, suspenseful children's story scene”。Librarian 会在向量数据库中的 ContextLibrary 命名空间里进行检索,并找到 blueprint_suspense_narrative,其中保存着供 Writer 使用的风格规则:

'output': { 'blueprint_json': '{
        "scene_goal": "Increase tension and create suspense.",
        "style_guide": "Use short, sharp sentences. Focus on sensory details...",
        ...
        }'
    }

这份蓝图中的 “Use short, sharp sentences(用短促有力的句子)” 和 “Focus on sensory details(聚焦感官细节)” 等指令,会在最后一步里成为 Writer 的风格规范。

第 3 步:Writer 综合生成最终输出

这最后一步,正是整个计划汇聚成结果的地方,也是上下文链式传递威力最直观的证明。

Executor 会先激活 Writer 智能体,但在这之前,它需要先解析计划中指定的依赖。

如果我们查看 trace 中第 3 步对应的 resolved_context,就会看到这个过程是如何发生的:计划中的占位符,已经被替换成前面步骤的真实输出。

'resolved_context': { 
    'blueprint': { 'blueprint_json': '{"scene_goal": "Increase tension..."}'},
    'facts': { 'summary': '- Operates in a polar orbit...'},
    ...
}

这就是关键证据。Writer 并没有直接拿到原始那篇 253-token 的长文;它拿到的是 Summarizer 压缩后的 110-token 摘要。此时,这个智能体所需的一切都已经齐备:

  • 一套风格指令(blueprint)
  • 一份核心事实摘要(summary)

于是,它最后一次调用 LLM,把这两份输入综合成一段最终叙事。

Summarizer 在这里成功扮演了“智能守门员”的角色:它保护了整个工作流中最昂贵的那个智能体,不让它承受不必要的上下文体量与成本压力。

接下来,我们就来看最终输出。

最终输出:风格与摘要化事实的综合体

引擎已经成功完成了一次复杂的、多智能体协同工作流的规划与执行。最终故事并不是一段泛泛的创意写作,而是之前几个智能体共同组装出的组件所生成的可追踪综合产物

我们可以清楚看到,Summarizer 和 Librarian 两者的影响,都贯穿在最终文本之中。这个故事精准地建立在 Summarizer 所提供的事实摘要之上:

  • 摘要里提到,Juno “Powered and stabilized by three very large solar-array wings”。故事开头就把这一事实转化成了第一人称体验:

I drift toward the giant. Quiet. Focused. My three large solar array wings stretch wide. They hum. They steady me. They drink sun.

  • 摘要还列出,Juno “Measures Jupiter’s composition, gravitational field, magnetic field, and polar magnetosphere”。故事则把这一科学任务内化成了一种感官行动:

I listen with metal ears. I measure composition. I feel gravity tug and weigh it. I trace the magnetic field, thread by thread. I sample the polar magnetosphere, bright with auroras.

与此同时,叙事风格又严格遵循了 Librarian 提供的 suspense blueprint。风格说明中要求 “Use short, sharp sentences”,而故事高潮部分就完美执行了这一规则,从而制造出节奏与张力:

Now. Flame. A steady roar. The craft shivers. Gravity clutches. I do not wobble. My wings keep me true.

通过这种对 trace 和最终输出的细致分析,我们已经获得了决定性证据:这次升级是成功的。我们不仅创造了一个新的、有价值的智能体,还把它无缝集成进了引擎的动态规划能力之中。现在,这台 Context Engine 不仅更强大,而且也更高效、更具成本意识,已经准备好去应对更高要求的企业级挑战。

不过,到这里还只是工程师视角的胜利。我们还没有把这一切真正翻译成业务价值。

将技术效率转化为业务价值

56.5% 的 token 压缩率,当然是一项值得肯定的技术成果,但上下文工程师的职责还不止于此。你还必须能够把这种效率,翻译成可被业务理解的真实价值。能够解释一个技术特性的“so what(这到底意味着什么)”,正是把开发者与企业中的战略伙伴区分开来的关键。

这要求我们把抽象指标——例如 token 数量——与具体业务结果——例如成本、速度与质量——连接起来。

设想一个假设但非常真实的业务案例:一家金融服务公司使用我们的 Context Engine,每天处理成千上万份冗长的市场分析报告,目标是为交易员提供简洁、可执行的摘要。现在,让我们量化一下 Summarizer 智能体在这个场景中的影响。

如果这家公司每天处理 10,000 份报告,而我们的智能体能够稳定地把最后那个最昂贵生成步骤所承载的 token 量减少 50% 以上,那么其财务影响将是显著的。仅仅这一个智能体,就有可能每月直接带来数千,甚至上万美元级别的 API 成本节省。图 6.6 展示了:新时代的 AI 工程师,必须既是架构师、也是上下文工程师,同时还要具备证明 AI 项目业务价值的能力。

image.png

图 6.6:新时代 AI 工程师的角色之一,是证明 AI 项目的业务价值

而且,这种价值还不止于成本节省,我们也必须能解释为什么。因为在把更小、更聚焦的上下文传给最终 Writer 的同时,我们实际上也降低了计算负担,从而带来更快的生成速度。这意味着交易员可以更快地拿到关键信息,从而实现更敏捷的决策。与此同时,摘要化上下文中更高的“信噪比(signal-to-noise ratio)”也可能提高最终输出质量,因为最后一个智能体不再容易被无关细节分散注意力。

能够把一次技术升级清晰表述为它对成本、速度与质量的影响,是一项非常关键的能力。正是这种能力,使上下文工程师能够有效地为自己的方案争取支持,并证明这些方案对企业底线(bottom line)的直接贡献。

既然我们已经成功设计出一套以效率为导向的解决方案,并且也证明了它的价值,现在就该对本章获得的关键能力与洞见做一个总结。

总结

在本章中,我们通过正面解决企业级场景中的 API 成本与上下文窗口限制问题,成功把 Context Engine 提升为一套在经济性上更高效的系统。我们在技术上的演进,是架构并实现了一个新的专用智能体——Summarizer,它被设计成大规模信息的智能守门员。通过把这个智能体整合进引擎的动态规划框架中,我们赋予了系统一种新的强大能力:主动式上下文管理(proactive context management)

我们的路径,也完全体现了一名真正上下文工程师的专业工作方式,而不只是“会写代码”而已。我们先从架构概念分析开始,随后系统化地实现了新智能体,并把它整合进可发现的 Agent Registry 中。更关键的是,我们对升级后的系统进行了严格验证,包括向后兼容性检查,以确保新功能不会破坏既有稳定性;随后,我们又通过一个复杂、真实世界风格的任务,证明了 Summarizer 的有效性。

通过这一过程,你已经掌握了构建企业级 AI 所必需的几项核心能力。你学会了如何为效率而设计架构,如何安全地扩展一个复杂 MAS,如何分析执行 trace,并以此为你的系统价值提供直接证据。下一章中,我们就将把这台 Context Engine 真正向外部世界打开。

问题

  • Summarizer 智能体的主要目标,是从外部来源中添加新的事实吗?(是或否)
  • count_tokens 工具函数会执行最终的内容生成 LLM 调用吗?(是或否)
  • 向后兼容性测试的设计目的,是为了证明新的 Summarizer 智能体本身工作正常吗?(是或否)
  • Planner 是否只需通过更新 agent registry,就能自动学会如何使用 Summarizer 智能体?(是或否)
  • 引入 Summarizer 智能体的主要业务原因,是为了提升最终输出的创造性吗?(是或否)
  • 在新的工作流中,Writer 智能体是否会直接从 Summarizer 智能体那里接收事实输入?(是或否)
  • 添加 Summarizer 智能体,是否要求对核心 engine.py 文件进行大幅修改?(是或否)
  • summary_objective 输入,是用于向 Summarizer 提供待压缩全文的吗?(是或否)
  • “主动式上下文管理”可以被视为本章引入的关键战略能力吗?(是或否)

参考文献

Hao, S., Wang, Z., Li, J., Liu, Z., & Chen, C. (2024). AgentVerse: A Flexible Framework for Multi-Agent Society Simulation. arXiv preprint arXiv:2405.08722.

Chen, L., Wu, Y., Zhang, Z., Xu, K., Wang, S., & Zhang, Y. (2024). AgentBoard: An LLM-Based Multi-Agent Platform for Proactive and Interactive Data Analysis. arXiv preprint arXiv:2407.03713.

Dasgupta, I., Hughes, E., Kuegel, A., Wang, F., Kay, J., & Collins, T. (2024). The Geometry of Context Management in Transformers. arXiv preprint arXiv:2405.00205.

延伸阅读

Wang, L., Ma, W., Zhu, Y., Wang, Z., Liu, S., & Liu, J. (2024). A Survey on Large Language Model-based Autonomous Agents. arXiv preprint arXiv:2308.11432.