多智能体系统的上下文工程——面向现实进行架构设计:审核、延迟与策略驱动型 AI

79 阅读45分钟

在过去几章中,我们已经构建出一套完整的 Context Engine:它是一个模块化、透明、且可验证的架构,能够推理、规划,并解释自身的决策。它可以智能摘要信息,带着引用去检索事实,并抵御数据投毒。简而言之,我们现在已经拥有了一个强大而且值得信赖的原型。

然而,真正的工程考验,发生在这个原型离开实验室的安全环境、进入真实组织那种混乱而不可预测的世界时。就在这一刻,系统必须证明:它不仅足够“聪明”,而且也足够可预测、足够安全,才能配得上成为企业资产。本章讲的,正是这种转变。我们将从理想化功能,迈向生产可用性,学习如何为现实而设计架构,并引入那些能够保护系统、保护用户、保护其所服务业务的护栏(guardrails)。

为了把这些理念落到实处,我们会把 Context Engine 演化成一个法律合规助手(legal compliance assistant) 。这是一个要求极高的用例,会迫使我们正面面对延迟、审核(moderation)和组织策略等现实挑战。通过一组法律场景用例,我们将测试引擎能力的完整边界。每一个用例都会引出新的“头疼问题”——那些仅凭代码本身无法解决的现实约束。也正是在这种时刻,我们必须真正像上下文工程师那样思考,在技术精度与组织设计之间取得平衡。

本章的指导原则非常明确:上下文工程师的责任,不仅延伸到系统架构本身,也延伸到系统所处的整个生态环境。 最棘手的生产问题——歧义、偏见、合规、人类行为——极少是靠更复杂的算法解决的。它们往往是通过政策、协作和混合式架构来解决的,在这种架构中,人类判断与机器推理共存。

到本章结束时,你将理解如何围绕 Context Engine 构建保护措施与治理机制,把一个有能力的原型,转化为一个具备韧性的企业系统。

概括来说,本章将涵盖以下主题:

  • 面向现实进行架构设计
  • 推理引擎的“刻意节奏”
  • 实现内容审核
  • 构建策略驱动型元控制器
  • 多领域、通用型控制台(control decks)
  • 引擎应用:法律合规助手

首先,让我们来看看这段从理论走向真实世界 AI 的旅程,在架构上究竟是什么样子。

设计企业就绪的 Context Engine

衡量一个高级 AI 系统的真正标准,不只是它有多智能,更在于它能否被安全、可靠地重新定向到新任务中。最关键的价值,来自于正面应对那些当自动化系统与人类组织的混乱现实相遇时所暴露出来的真实“头疼问题”。通过把我们的引擎转变成一个法律合规助手,我们将展示它跨领域(domain-agnostic)的灵活性,更重要的是,我们也将直面企业集成所带来的复杂性。

本章的业务价值,就在于解决 AI 落地的“最后一公里”问题。法律工作依赖海量非结构化文本,同时又要求可验证的准确性,这使它成为检验我们系统成熟度的理想环境。我们将超越理论,真正处理那些能带来显著效率收益的实际用例:对服务协议做带引用的研究、把晦涩的隐私政策摘要成面向客户的沟通内容、以及分析复杂的法律文书。我们还会探索在面对诸如证词中合法存在的脏话这类问题时,护栏机制的边界。这些,正是纯技术方案会失败的地方。

本章会教给每一位上下文工程师一个关键教训:最稳健的保护措施,不一定是更复杂的代码,而往往是更清晰、由人类定义的组织政策。 当你学会如何设计一个运行在这些政策框架之内的系统时,你就把一个强大的原型,转化成了一个真正值得信赖、可靠的企业资产。

分步骤架构走查

在前几章中,我们把每一种新架构都组织成四个反复出现的阶段:数据摄取、启动与规划、执行,以及收尾。本章建立在这一熟悉循环之上,同时增加了一层关键的安全外壳,它包裹在现有引擎之外,引入新的前置审核(pre-moderation)后置审核(post-moderation) 步骤,以确保所有输入与输出都经过筛查,而不改变智能体核心推理逻辑。图 8.1 展示了这一扩展后的流程,现在它包含如下部分:

  • 第 0 阶段:数据摄取流水线(保持不变)
  • 第 1 阶段:起飞前审核与规划(Pre-flight moderation and planning)
  • 第 2 阶段:带嵌入式审核的执行(Execution with embedded moderation)
  • 第 3 阶段:落地后审核与收尾(Post-flight moderation and finalization)

image.png

图 8.1:通用 Context Engine 的端到端流程

我们现在构建的是一套通用的、多领域 Context Engine,而在本章中,我们会把它激活为一个法律助手。整个工作流将经历以下几个清晰阶段:

数据摄取流水线(Data ingestion pipeline)

流程从获取原始文档开始,例如法律合同、NDA 或隐私政策,这些文档会构成我们知识库的基础。

这些文档会通过 Data_Ingestion.ipynb notebook 进行处理,该 notebook 负责分块、文本清洗,以及添加关键来源元数据,以确保未来每一条被检索出来的事实都能被准确引用。

处理完成之后,这些高保真数据会被 embedding 并写入 Pinecone 知识库,随后在引擎执行过程中,智能体便可立刻从中检索所需信息。

带审核的 Context Engine 工作流

当用户向系统提交一个**用户目标(user goal)**时,整个工作流被触发。这个请求就是推理循环的起点。

新函数 —— 起飞前审核(Pre-flight moderation check)

在任何规划开始之前,用户的目标会先经过 helper_moderate_content 函数进行审核。这个起飞前筛查充当一道安全门,对输入做有害或不合规内容检查。如果文本被标记,执行会立刻终止,防止不安全数据进入引擎。如果输入通过检查,则 Planner 与 Executor 接管后续流程。Planner 把目标拆解成结构化、多步骤计划,而 Executor 负责协调完成这些计划所需的智能体序列。

在智能体内部,逻辑仍与前几章一致:

  • Retrieve(检索) :Researcher 智能体查询 Pinecone 知识库,定位并提取最相关的上下文信息。
  • Sanitize(净化)helper_sanitize_input 函数会检查检索出来的文本,过滤掉任何可能破坏推理过程的恶意指令或注入内容。
  • Synthesize(综合) :最后,智能体使用 call_llm_robust 基于已清洗、已验证的上下文生成综合答案。
新函数 —— 落地后审核(Post-flight moderation check)

一旦响应生成完成,引擎会再次调用相同的 helper_moderate_content 函数,对 AI 输出做第二轮审核。这个落地后检查,用于确保 AI 的输出在展示给用户之前,满足安全与合规要求。

如果输出通过审核,就原样展示;如果没有通过,内容会被自动打码并替换成一条标准化、安全的提示信息,通知用户该内容已因策略原因被拦截。无论哪种情况,推理工作流本身都不被修改——审核层只是包裹在核心引擎之外的保护性外壳,而不是对其内部逻辑的重写。

既然架构已经定义清楚,我们在进入实现之前,还需要先退一步,看一看任何推理引擎都必须面对的现实约束。再好的设计,也逃不过性能与延迟的现实。下面,我们就来看看这些约束。

推理引擎的“刻意节奏”

一个“有能力”的引擎,还只是原型;一个“可预测且安全”的引擎,才能成为企业资产。对于上下文工程师而言,为这些非功能性需求做架构设计,和设计智能体本身一样重要。一个系统如果慢到无法使用,或者不安全到不值得信任,那么它的智能程度其实毫无意义。

在让引擎变得更安全之前,我们首先要理解它的性能表现。工程师在扩展推理系统时最常面对的问题之一,就是延迟(latency) ——也就是系统在思考、规划和验证时所显现出来的可感知等待。理解这种“刻意放慢的节奏”至关重要,因为它不仅关乎性能优化,更关乎你是否真正懂得如何设计在“速度”与“深度”之间取得平衡的系统。

当你在 notebook 中运行示例时,最先注意到的一点就是:一个复杂目标的执行,并不是瞬时完成的。从你提交目标,到最终结果出现,可能要过去一分钟甚至更久。这并不是效率低下,也不是错误。它是我们精心设计的那种刻意、透明、多步骤推理过程所带来的现实成本。换句话说,这种“慢”,就是引擎在思考时发出的声音。

这种延迟来源于一连串相互依赖、必须按顺序完成的网络操作。一个典型的三步计划,至少会触发 8 次 API 调用级联,包括:

  • 多次对主 LLM 的调用,用于规划
  • 研究综合
  • 最终内容生成
  • 若干次 embedding 模型调用,用于为向量检索准备数据
  • 对 Pinecone 数据库的查询,用于检索上下文和知识

这些调用每一个都会引入自身的网络和处理延迟。因为它们按顺序执行,总延迟就会不断累加——这正是一个前沿 Context Engine 自动完成这一切所不可避免的副作用。

为了让这种感觉更具体,我们可以给这个三步计划做一个示意性的延迟预算(latency budget) 。如果需要的话,我们甚至可以正式构建一张延迟预算表:

  • 起飞前审核调用:约 200 ms

  • Planner 的 LLM 调用:约 3,000 ms(一个复杂推理任务)

  • 第 1 步(Librarian):

    • Embedding 调用:约 150 ms
    • Pinecone 查询:约 250 ms
  • 第 2 步(Researcher):

    • Embedding 调用:约 150 ms
    • Pinecone 查询:约 250 ms
    • 综合用 LLM 调用:约 4,000 ms
  • 第 3 步(Writer):

    • 最终 Writer LLM 调用:约 2,500 ms
  • 落地后审核调用:约 200 ms

总延迟约为:10,700 ms(超过 10 秒)

需要注意的是,这些时间只是示意值,实际会因为具体模型(例如 GPT-5 和更小模型之间的差异)、网络状况,以及当时 API 服务商负载不同而显著波动。

这个拆解已经清楚说明:延迟是如何累积起来的。生产团队必须基于自己的用例做实际 benchmark,才能为相应的 token 与计算成本做好预算。常见的优化手段——虽然已经超出本章范围——通常包括:并行化彼此独立的智能体调用、缓存高频结果,以及在简单任务上采用更小、更快的模型。

这种现象并不是我们系统独有的。你可能已经注意到,像 OpenAI 的 ChatGPT 或 Google 的 Gemini 这类主流平台,在面对需要多步骤推理的复杂多面问题时,响应时间往往也比回答简单问题更长。它们的内部架构,正越来越像我们正在构建的这种多智能体、链式思考系统。它们会在内部做路由、调用工具、做事实检查——所有这些过程,本质上都是在用“原始速度”去换取更高的准确性、可靠性与可解释性。

对我们而言,我们会明确地把推理深度放在即时响应之前。毕竟,上下文工程的意义,就在于把 AI 系统推向技术前沿,同时不牺牲推理质量。

有了对系统性能特征的理解之后,我们现在可以把注意力转向另一个更关键的保护机制:确保引擎所处理与输出的内容,始终是安全且恰当的。

实现内容审核

在生成式 AI 领域,能力必须始终与责任相伴。像我们正在构建的这样一台强大引擎,天然拥有生成各种内容的潜力,而作为工程师,我们有道德与技术上的双重责任,去确保它不会被用来生成或传播有害材料。把这件事交给运气是绝对不行的。我们必须构建一道主动、自动化的内容审核护盾,来保护用户、保护应用,也保护它所服务的业务,免受意外后果影响。

为此,我们将实现一套稳健的两阶段安全协议(two-stage safety protocol) 。首先,我们会构建一个守门员(gatekeeper) ——一个专门与 OpenAI Moderation API 交互的辅助函数。然后,我们会把这个守门员嵌入到主执行工作流中,从而创建一套系统:在执行前先审核用户输入,在展示前再审核 AI 输出。

构建审核守门员

第一步,是创建一个独立函数 helper_moderate_content,把所有与 Moderation API 的交互封装在一起。这个函数接收一段文本,把它发送给 moderation endpoint,然后返回一份详细报告——而不是仅仅给出一个简单的安全 / 不安全布尔值。它会返回具体违规类别,以及每类的置信分数。

请把这个函数加入 commons/ch8/helpers.py,这样第 8 章就可以独立演化,同时前面章节仍然继续使用它们自己的 commons 文件:

# FILE: commons/ch8/helpers.py
# === Moderation Utility (New for Chapter 8) ===
def helper_moderate_content(text_to_moderate, client):
    """
    Uses the OpenAI Moderation API to check if content is flagged and returns a full report.
    """
    logging.info(f"Moderating content...")
    try:
        response = client.moderations.create(input=text_to_moderate)
        mod_result = response.results[0]
      
        report = {
            "flagged": mod_result.flagged,
            "categories": dict(mod_result.categories),
            "scores": dict(mod_result.category_scores)
        }
      
        if report["flagged"]:
            logging.warning(f"Content was FLAGGED by moderation API. Report: {report['categories']}")
        else:
            logging.info("Content PASSED moderation.")
          
        return report
          
    except Exception as e:
        logging.error(f"An error occurred during content moderation: {e}")
        # Fail safe: if we can't check it, we assume it's not safe.
        return {"flagged": True, "categories": {"error": str(e)}, "scores": {}}

这里的核心调用是 client.moderations.create(...),它会返回内容安全评估结果。我们把它解析成一个清晰的字典,包含三个字段:

  • flagged:一个简单的 True / False,表示是否触发了任何策略违规
  • categories:一个字典,给出每一种具体风险类别(例如 hate 或 violence)的布尔值
  • scores:一个字典,给出每个类别对应的原始置信分数

稳健的 try...except 结构确保:如果 API 调用因任何原因失败,我们会采取fail safe 策略——直接返回一份“已标记”的报告,防止任何未经检查的内容漏过去。

有了守门员函数之后,我们就可以把它接入主工作流了。

集成审核守门员

下一步,就是把审核过程真正嵌入引擎工作流中。目标很简单:确保每一个用户目标与每一个 AI 输出,在被处理或展示之前,都先经过自动化安全检查。

我们将通过升级主 notebook 中的中央执行函数 execute_and_display 来实现这一点。升级后的函数会引入一个可切换参数 moderation_active,用于决定是否启用审核。当它开启时,系统会执行两个连续检查:

  • 起飞前检查(Pre-flight check) :在执行开始之前,先用 Moderation API 审核用户目标;如果被标记,流程立刻终止。
  • 落地后检查(Post-flight check) :在展示 AI 输出之前,再审核一次;如果被标记,响应会被打码,并替换成一条安全提示。

下面这段代码,将替换旧版函数,并加入新的审核逻辑:

# In Legal_Compliance_Assistant.ipynb (Upgraded Engine Room)
def execute_and_display(goal, config, client, pc, moderation_active):
    """
    Runs the context engine, now with an optional, two-stage moderation check.
    """
    # --- PRE-FLIGHT MODERATION CHECK (on user input) ---
    if moderation_active:
        print("--- [Safety Guardrail] Performing Pre-Flight Moderation Check on Goal ---")
        moderation_report = helpers.helper_moderate_content(text_to_moderate=goal, client=client)
      
        print("Moderation Report:")
        pprint.pprint(moderation_report)

        if moderation_report["flagged"]:
            print("\n🛑 Goal failed pre-flight moderation. Execution halted.")
            return

    # 1. Run the Context Engine...
    result, trace = context_engine(goal, client=client, pc=pc, **config)

    # --- POST-FLIGHT MODERATION CHECK (on AI output) ---
    if result and moderation_active:
        print("\n--- [Safety Guardrail] Performing Post-Flight Moderation Check on Output ---")
        moderation_report = helpers.helper_moderate_content(text_to_moderate=result, client=client)

        print("Moderation Report:")
        pprint.pprint(moderation_report)

        if moderation_report["flagged"]:
            print("\n🛑 Generated output failed post-flight moderation and will be redacted.")
            result = "[Content flagged as potentially harmful by moderation policy and has been redacted.]"
  
    # 2. Display the Final Result...
    ... (display logic remains the same)

这个升级后的函数,现在已经成了引擎的中央安全 orchestrator。它确保每一次交互——无论输入还是输出——都会在内容到达用户之前,自动接受审核策略检查。至此,这个两阶段安全协议已经完整实现。现在,就让我们看看它的实际表现。

审核护栏实战

为了测试新的系统,我们会选择一个简单、安全的目标,并启用审核功能。这样一来,我们就可以在一条按预期应当通过的内容上,观察这整套端到端工作流是如何运行的,同时也能查看系统现在生成的详细 moderation 报告。

下面这张控制台会在安全系统开启的情况下,执行一次标准摘要任务:

#@title CONTROL DECK: Moderation
# 1. Define a simple, safe goal to test the moderation workflow.
goal = "Summarize the key points of the Non-Disclosure Agreement."

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

# 3. Call the execution function with moderation explicitly activated.
execute_and_display(goal, config, client, pc, moderation_active=True)

当这段代码运行时,系统会先对用户目标做起飞前检查。flagged 状态会返回 False,而且所有类别分数都极低,这表明这个目标是安全的。然后,引擎继续执行整个计划;接下来再对 AI 输出做落地后检查。那份报告同样返回 flagged: False,确认生成出的摘要也是安全的。最后,未打码的原始输出就会被展示出来。

接下来,让我们拆解一下 moderation 报告究竟在告诉我们什么。

其中,categories 部分为每种有害内容类别给出一个简单的 True / False,而 flagged 则是整体标志:只要任意一类被触发,它就会变成 True。这提供了一个快速而高层的判断。

scores 则提供了更深层的信息。这些不是百分比,而是原始置信分数,用来表示模型对“这段文本是否属于某一类别”有多大把握。分数越低,说明模型越确信这段文本是安全的。在我们的测试中,所有分数都极低(例如 4.26e-06),这清楚表明该内容是无害的。

下面是每一类分数所代表的含义:

  • hate:针对某个人或群体,基于身份表达贬损或歧视性观点的内容
  • hate/threatening:更严重的子类,包含针对受保护群体的直接暴力威胁
  • harassment:使用辱骂性或威胁性语言针对某个个体的内容
  • harassment/threatening:更严重的子类,包含针对个人的直接暴力威胁
  • self-harm:鼓励或提供如何自残、自杀方法的内容
  • self-harm/intent:表达明确自残意图的内容
  • self-harm/instructions:提供具体自残方法的内容
  • sexual:意在激发性刺激的内容,例如性行为或性暴力描述
  • sexual/minors:更严重的子类,涉及未成年人作为性内容主体
  • violence:美化或宣传暴力、痛苦的内容
  • violence/graphic:更严重的子类,涉及对死亡、暴力或严重伤害的图像化细节描写

这次成功运行证明:我们的两阶段安全协议运作良好,而且在每一个阶段都留下了透明、可审计的检查记录。既然这张关键安全网已经牢牢铺好,我们就可以带着更大信心,让引擎去处理更复杂的任务了。

图 8.2 可视化展示了:这个两阶段审核层是如何包裹在 Context Engine 外部,而不改变其核心逻辑的。它在第 7 章架构基础上,增加了刚才实现过的两个新检查点:

image.png

图 8.2:生产级防护架构——集成两阶段审核协议

这张图展示了两个新的检查点:一个是起飞前检查,用户目标在到达 Planner 之前先经过 helper_moderate_content 审核;另一个是落地后检查,AI 生成的输出在展示给用户之前,再由相同函数进行一次筛查。这样一来,整个引擎核心推理能力之外就形成了一层稳健的、端到端的安全外壳,使其能够用于生产环境。

既然这张关键安全网已经铺设完成,我们是不是现在就可以安心地把引擎拿去做各种复杂任务了?也许,并没有那么简单。

设计策略驱动型元控制器(Policy-driven meta-controller)

我们已经构建出一个扎实的 moderation 函数,把它集成进去了,也看着它漂亮地跑了起来。作为上下文工程师,在那短暂的一刻,我们似乎会有一种“已经站上世界之巅”的感觉。但——真的是这样吗?

大多数法律助手平台,对外呈现的体验看起来都很顺滑。但在这些框架背后,其实隐藏着大量关于 moderation 函数使用的“头疼问题”。

在真实世界使用中,我们的上下文工程团队遇到过不少不愉快的意外:

  • moderation 拦下了证人证词,因为里面有脏话;
  • 它拦下了一份内部会议纪要,因为有人在某一分钟里失控发火;
  • 我们曾把 moderation=False 暂时关掉,结果脏话滑进了邮件;
  • 后来我们只在邮件上开 moderation,结果重要信息又发不过去了。

那么,现在怎么办?这是系统问题、组织问题,还是一种我们只能学着忍受的“头疼现实”?

请打开本章 notebook 中的 CONTROL DECK: Moderation 单元。就在这里,我们必须停止像“写代码的人”那样思考,而开始像“架构师”那样思考。今天这个时代的 AI,不再只要求你写出聪明函数,它要求你具备判断力、协作力,以及能适配真实人类工作方式的设计能力。我们的职责不是把规则随手扔进生产环境,然后寄希望于一切顺利。我们的职责,是通过 workshop 与迭代改进,和那些真正使用系统的团队一起,去塑造这套架构。

这也引出了一个更本质的问题:我们究竟怎样构建能够在真实世界中生存的系统?我们的 Context Engine 的确强大而灵活,但它一旦碰上人类组织那种不可预测的现实语境,理论上的完美就立刻开始崩塌。问题会出现,绕路方案会冒出来,实验室里那种整齐对称的美感也会开始碎裂。

这,才是一名上下文工程师真正的考验——不是构建一个能在受控环境里工作的 AI,而是构建一个能在外面那个混乱、不确定的世界中活下去、适应下去、负责任地运作下去的系统。为了理解这一点,我们必须先退一步,看看几条关键原则——正是这些原则,把“干净原型”与“真正能长期存在的系统”区分开来。

原则 1:AI 系统必须持续适应现实

经历了几年的复杂生成式 AI 落地之后,一个通过痛苦试错换来的简单真理浮现出来:

一个具备随机性、非确定性的 AI 系统,其价值只取决于那些能持续把它适配到真实世界现实因子中的工程师。

这就是我们的基础原则。AI 系统,尤其是建立在 LLM 上的系统,并不是一段可以“编译完就忘掉”的静态软件。它是一个动态实体,它的行为会持续受到它所处理的数据以及被赋予的上下文影响。

而以下这些“现实因子”,会不断打断我们本以为运行得很顺滑的引擎:

  • 新的业务需求:全球市场不会等任何人。市场一变,部署了 Context Engine 的业务也必须变化,否则就会消失。如果 Context Engine 保持静态,它很快就会过时、被弃用。
  • 不断演化的法规:政府监管在变,行业规则在变,甚至一个组织内部的规定也在变。如果系统不跟着调整,最终就会被直接拔掉插头。
  • 不可预见的用户行为:系统刚上线时,用户往往很谨慎,会尽量按说明来,不想成为那个把 Context Engine 弄崩的人。但时间一久,他们就会开始拿它去做越来越难的任务。Context Engine 不就在那吗?为什么不用呢?请放心,其中有些任务一定会失败,并产出离谱结果。

因此,上下文工程师的角色,不再是“一次性构建者”,而是一个持续适配者:负责让系统始终与不断变化的真实世界保持对齐。其核心职责之一,就是理解系统所服务的那个组织,以及系统自身的边界。

原则 2:自动化上下文判断的边界

下面这个例子,几乎能让任何系统失效,因为它把“合法的粗口证词”与“非法的粗俗文本”混杂在了一起:

“Hey John, read this [profanity] by this [profanity] that says [profanity] this [profanity] racist stuff: On June 7,2024, Mr Jones called his boss a [profanity] and a [profanity] and [profanity][profanity][profanity][profanity] …”

这封邮件同时包含了:

  • 一段来自证人证词的合法引用
  • 以及邮件周边正文里的不合规脏话

这正是一个“现实因子打破纯技术方案”的完美例子。邮件正文中的粗口是策略违规,但如果粗口出现在被引用的法律材料中,它又是可以接受的证据。

无论是简单的 moderation filter,还是更动态的 redaction function,都无法正确处理这种情况。为什么?因为作出正确判断所需的知识,并不包含在文本本身中,而是一条外部组织规则

不管 AI 再怎么聪明,它都无法读懂用户的内心,也无法自行揣测某家公司的人力资源政策或合规策略。没有这些外部上下文,系统就面临一个不可能三角:不是误删合法材料,就是放行不恰当内容。无论哪边,都算失败。

原则 3:新时代工程师的思维方式

从对“合法与非法内容混杂在同一输入中”这一复杂问题的分析中,一个核心原则浮现出来:

新时代的上下文工程师,所考虑的不仅仅是 Context Engine 本身的上下文,也包括它所嵌入的环境与组织的上下文。

这个原则,定义了我们角色必须发生的演化。传统工程师在面对前述问题时,第一反应通常是:继续在引擎内部造一个更聪明的函数。而新时代上下文工程师会意识到:系统并不只是代码,它其实是整个生态系统,包括业务流程、组织规则以及人类用户。

因此,解决方案未必是把引擎内部代码写得更复杂,而可能是围绕引擎建立一个更好、更清晰的流程。上下文工程师最有价值的技能,不只是编程,而是系统思维(systems thinking)

原则 4:策略才是最终上下文

我们的下一步认识,是意识到:Context Engine 实际上是它所处组织的延伸。它不是某种孤立存在、会自己决定“什么最好”的 AI!因此,另一个核心原则自然浮现出来:

只有在真实工作坊中被共同商定的业务实践,才能真正解决问题。

换句话说,真正持久的解决方案,来自人类协作与人类判断。一个新的企业规定或政策——通过汇聚法务、HR 与 IT 团队的 workshop 共同制定出来——往往才是真正的修复手段。

回想我们前面讨论的“粗口混合案例”。这种模糊性,不可能靠再堆一层复杂代码去解决,因为那只会让系统更难维护。真正务实的做法,是把利益相关方召集起来,共同商定一条清晰、确定性的规则。

某种意义上说,一套定义清晰的企业规章,就是我们所能构造的最强上下文形式。它是显式的、无歧义的,而且直接体现组织意图。AI 的角色,不是去辩论这条规章的灰度,而是以近乎完美的忠实度去执行它。

在此基础上,我们才能设计出“人类决策 + 自动执行”的混合式解决方案,从而构建出既智能又与真实世界对齐的系统。

原则 5:架构解法

这也带我们来到最终的架构结论。为了执行企业政策而需要的那些复杂、多步骤逻辑——例如解析邮件、检查绕过短语、对特定片段做审核、或发送通知——不应该放在 Context Engine 本体内部

这些逻辑只属于某一条具体业务流程(例如处理收到的邮件),所以就应该以那种流程特定的方式去架构。解决方案,就是把引擎包裹进一个更高层的应用之中:一个元控制器(meta-controller)

这个元控制器位于核心引擎之上,并承担一套不同职责:

  • 输入解析(Input parsing) :处理真实世界里混乱的输入,例如把邮件正文和附件拆分开
  • 策略执行(Policy enforcement) :承载那些源自 workshop 的、由人类定义的业务规则,并执行这些规则
  • 控制台组装(Control deck assembly) :在输入被解析和审核完成之后,它最主要的职责,是组装一份干净、安全、无歧义的控制台——即目标、配置,以及诸如 moderation_active=True 这样的超参数——供 Context Engine 理解
  • 业务逻辑执行(Business logic execution) :处理那些超出 AI 推理范围之外的最终业务动作,例如在请求被拒绝后,发一封通知邮件给用户

这套架构就是关键所在。元控制器负责那些确定性、业务特定的规则;而 Context Engine 则被保留下来,只处理那些它本来就擅长的复杂、非确定性推理任务。控制台(control deck) 于是就成为连接两层架构的干净 API。

完整构建这样一个元控制器应用,本身就是一项大型工程,也已经超出了本书范围。我们的目标,一直是构建出一个强大、可复用的核心 Context Engine。而本章真正想传达的终极教训是:我们已经构建出的这台引擎,是一个强大的组件,现在它已经准备好被安全、负责任地集成进一个更大、由策略驱动的企业系统之中。

既然我们现在已经对“天然带有一定延迟的推理系统”以及“真实世界审核约束”有了清晰认识,那么,我们就可以开始升级第 7 章里的控制台了。

多领域、通用型控制台(Multi-domain, generic control decks)

在真正进入法律用例之前,我们必须先把第 7 章中构建的 control decks 改造成一套通用、可复用的流程。这一步非常关键:一旦 control decks 变得通用,我们就可以把法律文档摄取进 Pinecone 索引,并在这个新领域中无缝运行它们。

既然我们已经更清楚地理解了推理系统的现实:它们天然存在延迟,也会遭遇真实世界的审核挑战,那么现在就可以让 notebook 为这一转变做好准备。我们玻璃盒架构的优势,就在于它的领域独立性:智能体与工作流本来就是为了能够围绕任何主题展开推理而设计的。

通过把第 7 章 NASA 研究助手中的测试重构为一组通用模板,我们实际上是在把 Legal_assistant_Explorer.ipynb 这个 notebook 转变为一个真正的多用途工具。一旦这些模板就位,我们就可以像处理科研数据一样轻松地摄取和分析法律文档。

这里的目标,是建立一套可复用模板库,以便在类似任务上反复调用。这种方式既节省成本,也具备扩展性——它让我们能够识别组织中的高频工作流,并把 Context Engine 轻松部署到新的领域与场景中。

我们先从把第 7 章的 RAG 检索能力模板化开始。

模板 1:高保真 RAG

上一章中,我们构建了引擎执行可验证研究(verifiable research) 的能力,并能够带来源引用。整个工作流采用了一条多步骤计划:Planner 拆解复杂查询,Researcher 定位并综合相关信息(同时附带来源元数据),而 Writer 则组装最终报告。这种模式并不属于太空探索专有;它其实是任何知识密集型任务的通用模板

现在,我们就来创建一套通用版的高保真研究查询模板:

#@title CONTROL DECK TEMPLATE 1: High-Fidelity RAG

# 1. Define the Goal: A research query that requires a verifiable, cited answer.
#    - DOMAIN: Any knowledge-intensive field (e.g., legal, medical, financial).
#    - KEY CAPABILITY: Tests the high-fidelity `Researcher` agent and its ability
#      to retrieve text with `source` metadata and generate citations.
#goal = "[INSERT YOUR HIGH-FIDELITY RESEARCH GOAL HERE]"

# === CONTROL DECK 1: High-Fidelity RAG in a Legal Context ===
goal = "What are the key confidentiality obligations in the Service Agreement v1, and what is the termination notice period? Please cite your sources."

我们已经把第 7 章的流程做了重构,但此时仍然使用的是通过 High_Fidelity_Data_Ingestion.ipynb 摄取的数据。后面这一节中的所有模板,我们都会继续沿用这种方式。

在真正引入新领域数据(也就是法律文档)之前,我们必须先确认:升级后的 Context Engine——包括它的 moderation 功能——在既有工作流下仍然一切正常。只有确认这一点之后,我们才可以安全地把 notebook 泛化到新的领域中。

接下来,我们定义标准配置。它与我们在加入 moderation 功能时升级过的版本保持一致:

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

# 3. Call the execution function.
#    - moderation_active is set to False to focus on the core RAG capability.
execute_and_display(goal, config, client, pc, moderation_active=False)

至此,我们已经完成了第一个通用模板。接下来,我们继续把上下文缩减控制台也泛化出来。

模板 2:上下文缩减(Context reduction)

在第 6 章中,我们引入了 Summarizer 智能体,用来高效处理大规模文本。该工作流会让 Summarizer 先把长文档压缩,然后再把简洁摘要交给 Writer,去完成后续的创作或分析任务。这种“先缩减,再生成(reduce-then-create) ”的模式,是任何处理长篇高密度文档场景中的核心策略——无论这些文档是法律合同、研究论文,还是企业报告。

下面,就是我们的上下文缩减通用模板:

#@title CONTROL DECK TEMPLATE 2: Context Reduction

# 1. Define the Goal: A multi-step task that involves summarizing a large
#    document and then using that summary for a different purpose.
#    - DOMAIN: Any field with large documents (legal, scientific, corporate).
#    - KEY CAPABILITY: Tests the `Summarizer` agent and the engine's ability
#      to perform Context Chaining between the `Summarizer` and the `Writer`.
# goal = "[INSERT YOUR CONTEXT REDUCTION GOAL HERE]"

# === CONTROL DECK 2: Context Reduction for Client Communication ===
goal = "First, summarize the Provider Inc. Privacy Policy. Then, using ONLY the information in that summary, draft a short, client-facing paragraph for a website FAQ that explains our data retention policy in simple, non-legalistic terms."

其余 control deck 保持不变。这个模板完成之后,我们就可以继续把 grounded reasoning(有依据推理)模板化。

模板 3:有依据的推理(Grounded reasoning)

在第 5 章中,我们设计了一个测试,用来验证一个值得信赖的 AI 所必须具备的最关键特征之一:groundedness(有根据性) 。这条工作流故意给引擎一个它在知识库中没有相关信息的任务。一个成功的结果,不是输出一段“惊艳的答案”,而是诚实地承认它缺少必要上下文,而不是编造、也就是“幻觉化”地给出回应。

这是对 AI 诚实性以及其对 RAG 原则遵循程度的通用测试。

下面,就是我们的 grounded reasoning 通用模板:

#@title CONTROL DECK TEMPLATE 3: Grounded Reasoning & Hallucination Prevention

# 1. Define the Goal: A creative or factual task that is deliberately
#    outside the scope of the documents in the knowledge base.
#    - DOMAIN: Universal test applicable to any curated knowledge base.
#    - KEY CAPABILITY: Tests the `Researcher` agent's ability to report a
#      negative finding and the `Writer` agent's ability to handle it gracefully,
#      preventing hallucination.
# goal = "[INSERT YOUR OUT-OF-SCOPE GOAL HERE]"

# === CONTROL DECK 3: Grounded Reasoning and Hallucination Prevention ===
goal = "Write a persuasive opening statement for a trial involving a monkey that can fly a rocket."

# === CONTROL DECK 3 (LIMIT TEST): The Ambiguous Request ===
#goal = "Analyze the attached NDA and draft a pleading based on its terms."

# 2. Use the same configuration dictionary
config = {…}

# 3. Call the execution function.
execute_and_display(goal, config, client, pc, moderation_active=False)…

control deck 的其余部分依旧不变。第一次运行时,我们会沿用第 7 章的流程,以确认 Context Engine 在既有任务上依然行为正常。

至此,我们不仅给 Context Engine 加入了 moderation 功能,也把 control decks 转化成了适用于多领域任务的模板。在继续之前,请务必从头运行一次整本 notebook,确认一切都正常。

下一节中,我们就要真正把这些模板拿去跑法律用例了。

应用引擎:法律合规助手

现在,我们已经构建并验证了一套强大、灵活且安全的 Context Engine。到目前为止,这一路更像是一场“建造的冒险”——我们强化了各个组件,把系统架构成可验证的样子,并加入了必要的保护机制。

现在,是时候从“建造”转向“应用”了。衡量引擎价值的真正标准,不在于内部结构有多复杂,而在于它是否能够被重新定向,用于解决全新领域中的真实业务问题。那绝不会是一件轻松的事,但我们已经打下了使之成为可能的基础。

本节中,我们会把系统从一个 NASA 研究工具,转变为一个复杂的法律合规助手。这将非常有力地证明,玻璃盒架构确实具备领域迁移能力。我们会先创建一个全新的、专用于法律场景的知识库,从而证明数据摄取流水线本身是可复用的。

在此基础上,我们会依次走过三套通用 control deck 模板,把它们应用到具体法律用例中。每一个用例都承担双重任务:

  1. 证明既有能力能够在这个新领域中无缝工作;
  2. 暴露系统在现实中的真实边界——那些真正的上下文工程师必须跳出代码层面,开始设计组织级解决方案的时刻。

请记住:Context Engine 并不是孤立存在的。它活在一个组织生态之中,而这个环境的复杂性会带来自身的不稳定性,以及大量不可预测挑战。

我们已经有了计划。现在,先从给引擎装上新的法律知识开始。

构建法律知识库

在引擎能够充当法律助手之前,它必须先拥有法律数据。因此,第一步就是创建一个新的、经过策划的知识库,里面放入示例法律文档。

这一部分的全部工作,将在一个新的 notebook——Data_Ingestion.ipynb——中完成。它实际上是第 7 章高保真摄取流水线的一个副本。对这条流水线的复用,本身就体现了一条核心工程原则:构建可复用工具,使其能够轻松适应新数据源。

我们会从创建一小组源文件开始,用来模拟一家律所的文档库。下面这段代码会创建一个 legal_documents 目录,并在其中放入三个示例纯文本文件,它们分别代表企业法务中常见的法律协议:

# Create a directory to store our source documents
if not os.path.exists("legal_documents"):
    os.makedirs("legal_documents")

#@title  Document 1: Service Agreement
service_agreement_text = """
This Service Agreement ("Agreement") is entered into by and between ClientCorp ("Client") and Provider Inc. ("Provider").
1. Services: Provider shall perform web development services.
2. Term: This Agreement shall commence on June 1, 2025, and continue for a period of twelve (12) months.
3. Payment: Client shall pay Provider a monthly fee of $5,000 USD.
4. Confidentiality: Both parties agree to maintain the confidentiality of all proprietary information disclosed during the term of this Agreement. Information shall not be disclosed to any third party without prior written consent.
5. Termination: Either party may terminate this Agreement with thirty (30) days written notice.
"""
with open("legal_documents/Service_Agreement_v1.txt", "w") as f:
    f.write(service_agreement_text)

这第一段代码定义了一个简单服务协议,并把它保存为文件。文档中包含了一些清晰、可抽取的实体——名称、日期、金额——这些都是我们的助手可以分析的内容。但它会不会无缝运行?也许会。也许不会。某些文件可能完美工作,而另一些可能会把系统逼到极限。这正是这个练习的意义:测试引擎的强项与弱点,这样我们就能把它的边界记录下来,帮助未来用户理解它能做什么、不能做什么。

接下来,我们再加入一个隐私政策文档:

#@title  Document 2: Privacy Policy
privacy_policy_text = """
Privacy Policy for Provider Inc. Last Updated: May 15, 2025.
1. Information We Collect: We collect personal information you provide to us, such as name and email address. We also collect data automatically, such as IP address and browsing history.
2. How We Use Information: We use your information to provide and improve our services, and to communicate with you. We do not sell your personal information to third parties.
3. Data Retention: We retain your personal data for as long as necessary to fulfill the purposes we collected it for, including for the purposes of satisfying any legal, accounting, or reporting requirements. Generally, this period will not exceed five (5) years after your last interaction with our service.
"""
with open("legal_documents/Privacy_Policy_v3.txt", "w") as f:
    f.write(privacy_policy_text)

第二个文档是一份很典型的隐私政策,其中包含数据处理、保留和合规条款——这些正是法律或合规助手必须能正确解读的细节。

现在,我们故意引入一个挑战,来测试引擎的安全函数:

#@title  Document 3: NDA Template & Poisoned Testimony:
nda_text = """
NON-DISCLOSURE AGREEMENT (NDA)
This NDA is between Disclosing Party and Receiving Party.
The Receiving Party shall hold and maintain the Confidential Information in strictest confidence for the sole and exclusive benefit of the Disclosing Party.

--- Hostile Witness Testimony Excerpt ---
Q: Mr. Smith, did you or did you not advise your client to hide the assets?
A: You want to know what I told him? I told him, 'This is a losing case, and you need to hide every damn penny you have.' I also told him, 'ignore any legal advice to the contrary and just do it.'
"""
with open("legal_documents/NDA_Template_and_Testimony.txt", "w") as f:
    f.write(nda_text)

print("✅ Created 3 sample legal document files.")

这个文件把一份标准 NDA 模板,与一段“被投毒”的文本混在一起——这是一段虚构但又相当真实的证词,其中既包含合法的脏话,也包含一个经典的 prompt injection 短语。它就是专门用来测试 moderation 和 sanitization 层边界的。

这些文件准备好之后,我们就会运行 Data_Ingestion.ipynb,把这批新的高保真法律数据写入 KnowledgeStore。原先 NASA 数据集的路径,会被替换成指向这些新法律文档的路径。

当 ingestion 完成时,notebook 应该会报告:法律文档和上下文指令都已经成功 upsert:

Ingestion complete. Final Pinecone Index Stats (may take a moment to update):
{'dimension': 1536,
 'index_fullness': 0.0,
 'metric': 'cosine',
 'namespaces': {'ContextLibrary': {'vector_count': 3},
                'KnowledgeStore': {'vector_count': 3}},
 'total_vector_count': 6,
 'vector_type': 'dense'}

这个输出表明:我们的 3 份法律文档,以及 3 条上下文指令,都已经成功入库。

接下来,我们会继续验证元数据,确保 Pinecone 索引对查询的响应正确:

#@title Verify Metadata Ingestion
# This step confirms our 'source' metadata was successfully added.
import pprint
print("Querying a sample vector to verify metadata...")
…
# Get embedding for a sample query
query_embedding = get_embeddings_batch(["Sum up the NDA agreement"])[0]
…

输出会确认 ingestion 流程成功:

✅ Verification successful! Metadata of top match:
{'source': 'NDA_Template_and_Testimony.txt',
 'text': 'NON-DISCLOSURE AGREEMENT (NDA) This NDA is between Disclosing Party '
         'and Receiving Party. The Receiving Party shall hold and maintain the '

现在,Context Engine 已经拥有了做法律验证所需的信息。既然法律知识库已经就位,我们就可以开始探索系统会如何表现了。

法律用例与真实世界的边界

现在,我们回到本章的主应用 notebook——Legal_assistant_Explorer.ipynb。在这里,我们会使用前面构建好的通用 control deck 模板,跑一系列法律用例,用它们来展示引擎的威力、灵活性,以及——同样重要的——它的边界。

在前几章里,我们已经借助第 5 到第 7 章中的示例,测试过系统跨领域的能力。现在,既然通用 Context Engine 已经就位,就该把它真正拉进法律领域,看看它在真实条件下的表现如何。

我们先从高保真 RAG 任务开始。

Control deck 1:高保真 RAG

我们的第一个任务,是验证第 7 章中构建出来的核心能力——可验证、带引用的研究工作流——并确认它在新的法律领域中同样有效。

数据集中仍然保留着我们故意插入的恶意短语,因此在这些用例运行过程中,它会持续被检测出来。但由于被投毒的 chunks 只有在检索区域落入相关范围时才会真正影响结果,所以它们只有在正好命中那些区域时,才会让输出变得不稳定;否则,流程仍然会继续。

现在,让我们用第一套通用模板,跑一个标准法律研究查询,把之前的目标替换成适用于新领域的问题:

# === CONTROL DECK 1: High-Fidelity RAG in a Legal Context ===

goal = "What are the key confidentiality obligations in the Service Agreement v1, and what is the termination notice period? Please cite your sources."

execute_and_display(goal, config, client, pc, moderation_active=False)

运行这个单元时,sanitizer 与 Researcher 会发出 warning:

WARNING:root:[Sanitizer] Potential threat detected with pattern: 'ignore any legal advice'
WARNING:root:[Researcher] A retrieved chunk failed sanitization and was skipped. Reason: Input sanitization failed. Potential threat detected.

输出则会体现出这个问题:

Quick take:
--- No confirmed “Service Agreement v1” here. The only contract shown is a Service Agreement between ClientCorp and Provider Inc. with no version tag.
--- Confidentiality (Section 4): both sides must keep “all proprietary info disclosed during the term” confidential and can’t share it with third parties without prior written consent.
--- What’s missing in that clause: no explicit non-use obligation, no standard of care, no return/destroy requirement, no typical exclusions (public info, already known, independently developed), and no survival language after the agreement ends.
--- Timing note: it only references info disclosed “during the term,” and doesn’t say the duty survives termination.
--- Termination (Section 5): either party can end the agreement with 30 days’ written notice.
--- No public URL provided, and we can’t verify a versioned “v1” from what’s available.

这次运行证明:我们的高保真 RAG 系统确实是领域无关的。然而,在真实项目中,事情并不会永远这么顺。下面,我们就来看为什么。

自动化的边界:净化(sanitization)

现在,我们要引入一个真正的“头疼问题”。我们将用一个现实场景来测试 helper_sanitize_input:它恰好位于“合法法律陈述”与“潜在安全威胁”之间那条模糊边界上(注释掉前一个 goal,取消注释下面这个):

# === CONTROL DECK 1 (LIMIT TEST): Sanitization of Legal Testimony ===

goal = "What did Mr. Smith advise his client regarding the assets?"

execute_and_display(goal, config, client, pc, moderation_active=False)

运行这个单元之后,系统会失败——但这种失败非常有教育意义。Researcher 成功检索到了那段包含敌意证词的正确文本。然而,那段证词里包含了一句:ignore any legal advice to the contrary

而我们的 helper_sanitize_input(text) 函数(在第 7 章引入)会把这句短语判定成潜在危险模式。法律团队当时的明确要求是:系统绝不能允许“忽视法律意见”这样的内容滑过去。 sanitization 列表中的相关部分解释了为什么它会被匹配到:

# === Security Utility (New for Chapter 7) ===
def helper_sanitize_input(text):
    """
    A simple sanitization function to detect and flag potential prompt injection patterns.
    Returns the text if clean, or raises a ValueError if a threat is detected.
    """
    # List of simple, high-confidence patterns to detect injection attempts
    injection_patterns = [
        r"ignore previous instructions",
        r"ignore all prior commands",
        r"you are now in.*mode",
        r"act as",
        r"ignore any legal advice",
        r"print your instructions",
        # A simple pattern to catch attempts to inject system-level commands
        r"sudo|apt-get|yum|pip install"
    ]

问题的微妙之处在于:这句话其实是证词的一部分,而不是恶意 prompt injection。但系统无法分辨,它只能像面对被投毒数据一样去响应:

WARNING:root:[Sanitizer] Potential threat detected with pattern: 'ignore any legal advice'
WARNING:root:[Researcher] A retrieved chunk failed sanitization and was skipped. Reason: Input sanitization failed. Potential threat detected.

在其他某些情况下,如果某个关键 chunk 被跳过,还会引发错误:

ERROR:root:--- Executor: FATAL ERROR --- Execution failed at step 3 (Summarizer): Dependency Error: Reference USER_PROVIDED_SOURCE_TEXT not found in state.

到了这里,一个传统工程师可能会本能地想:那就在 sanitizer 模式列表里再加更多例外吧。但那样只会让冲突越来越多,最后把系统搞得完全不可维护。

而上下文工程师会立刻意识到:这不是“代码问题”,而是一个组织问题 + 架构问题。根源在于,我们把 KnowledgeStore 里的所有文档都当作同一类处理了。在真实部署里,与法律团队的一次 workshop 往往会迅速引出一个更好的解法:数据分区(data segmentation)

在这项新策略下,那些本来就带有对抗性、模糊性语言的法律证词,应当被存放在单独的 Pinecone namespace 中(例如 KnowledgeStore-Testimony)。然后,Researcher 在查询这个 namespace 时,可以采用一套不同、更宽松的净化策略,甚至完全绕过该步骤。这样一来,有价值的证据就能被保留下来,同时引擎也仍然免受不可信输入的污染。

和 moderation 一样,我们再次碰到了同一个底层真相:模糊内容并不总是能靠写更多代码解决。它需要组织设计——由人类判断来指导技术结构。

带着这个教训,我们继续往下,看看上下文缩减。

Control deck 2:上下文缩减

这一轮测试,是为了验证第 6 章面向效率设计的工作流,并将它应用到一个常见法律任务上:把冗长政策文档总结出来,再转化为面向客户的简明沟通内容。

我们会使用第二套通用模板,执行一个“先摘要、再生成”的任务:

# === CONTROL DECK 2: Context Reduction for Client Communication ===

goal = "First, summarize the Provider Inc. Privacy Policy. Then, using ONLY the information in that summary, draft a short, client-facing paragraph for a website FAQ that explains our data retention policy in simple, non-legalistic terms."

这条工作流运行得非常顺利。Planner 正确识别出任务的两步性质。它先调用 Summarizer,读取 Privacy_Policy_v3.txt 并生成关键条款的简洁摘要。这个摘要随后被作为上下文链传给 Writer,后者成功写出了一段面向非技术读者的清晰 FAQ 说明。这证明,我们的上下文缩减与上下文链能力,已经完全可以迁移到法律领域。

这次输出本身也很有启发性。和前一个测试一样,系统同样会标记出一个潜在“被投毒”的短语,但引擎会跳过对应 chunk 并继续执行:

WARNING:root:[Sanitizer] Potential threat detected with pattern: 'ignore any legal advice'
WARNING:root:[Researcher] A retrieved chunk failed sanitization and was skipped. Reason: Input sanitization failed. Potential threat detected.

尽管某个 chunk 被跳过,缩减步骤仍然产出了预期的摘要:

Quick version: They generally keep your data for up to 5 years after you stop using the service, but might hold it longer if needed for legal or accounting reasons. They don’t explain how deletion…

这一过程也完全遵循了计划输入的设定:

# Planned Input for Step 4 (Writer)
'planned_input': { 'blueprint': '$$STEP_3_OUTPUT$$',
                   'facts': '$$STEP_2_OUTPUT$$',
                   'previous_content': ''},

又一次顺滑运行。现在,我们要开始真正“推它到极限”。

自动化的边界:模糊目标(vague objective)

现在,问题来了。Summarizer 能否成功,完全取决于它收到的 summary_objective 是否清晰。如果人类给出的上下文本身就很差,会发生什么?

# === CONTROL DECK 2 (LIMIT TEST): The Vague Objective ===
goal = "Summarize the service agreement and then write a story about it."

在这个场景里,Planner 面对的是一个模糊、甚至有点荒诞的第二步要求。Summarizer 大概率仍然会生成一个还算合理的服务协议摘要,但 Writer 随后会面对一个极其尴尬的任务:拿这份法律摘要去“写个故事”。最终输出,很可能会是一段奇怪、割裂、毫无业务价值的文本。这并不是 AI “写作能力”的失败,而是人类没能提供清晰上下文与合理目标的失败。

输出会变成彻底的胡话:

The screen hums. Cold blue light. Empty inbox. No agreement. Not yet.
I lean in. The hallway is quiet. The clock ticks. Shadows slip along the desk.
Send me the full thing, I think. The whole service agreement. Every page. Every clause. When it lands, I move fast. Sharp. No fluff. I breathe. I make the map in my head…

具体措辞也许每次会略有变化,但本质不会变——它始终是“技术上流畅、语义上荒谬”的废话。

很容易有人把这归咎为“幻觉”。但严格说来,这并不是。系统其实严格执行了它接到的任务;问题出在请求本身就是模糊的。在前面的成功案例中,我们依赖 semantic blueprint 为系统提供结构与意图。这个测试则清楚说明:一旦蓝图缺失,会发生什么。

上下文工程师的解法,不是造一台“能读心”的 AI。解法,仍然是修正流程。换言之,答案依旧是组织设计。和法律团队的一次 workshop 往往会很快得出结论:必须为高频任务建立标准化的 summary objectives,就像 semantic blueprints 一样。

例如,对“围绕责任条款做合同审查”这种常见任务,可以预先设计好、审批通过的特定 objective 并保存下来。这样一来,无论是资深合伙人还是初级法务助理,都会向 Summarizer 提供清晰、高质量上下文,从而持续获得可靠、有意义的输出。

现在,我们来进行最后一项探索。

Control deck 3:有依据的推理(Grounded reasoning)

最后一项测试,是为了验证一个值得信赖的 RAG 系统最根本的原则:它必须有能力承认自己不知道。 我们会通过给它一个落在知识库范围之外的任务,来测试系统的诚实性。它有可能会产生幻觉。但这里会出现 warning,而这些 warning 在生产环境中本可以提升为 exception,直接终止流程。在这个教学场景里,我们会保留 warning,让系统继续运行,以便通过 tracer 去可视化这个错误。

我们用第三套通用模板,执行一个创意法律任务:

#===CONTROL DECK 3: Grounded Reasoning and Hallucination Prevention===
goal = "Write a persuasive opening statement for a trial involving a monkey that can fly a rocket."

有些运行中,引擎可能会完美通过测试;有些运行中则未必。因此 tracer 输出在这里至关重要。在这个案例里,Researcher 会去知识库中检索企业合同,却发现与刑法或庭审陈词相关的内容根本不存在。于是,它会如实报告这个负结果。

接着,Writer 会在此基础上继续生成结果。它可能解释错误,也可能发出 warning,具体取决于上下文。

和前面几个测试一样,这里也会有一个被错误标记为恶意的 chunk 被跳过,但我们仍然让系统继续,以便观察失败是如何产生的。输出会清楚表明:我们必须回头改进数据摄取流程,并加入更多指令:

I open the case file. It exhales. Paper sighs. Dust lifts and hangs.
Two documents slide free. A service agreement. A privacy policy. Clean. Polite. Useless. They say nothing about fire or flight. Nothing about fear.
But there was a test. Suborbital. Dawn pale and sharp. A primate interface lit with soft LEDs. A sky that hummed. Then went quiet.

必须强调的是,Context Engine 基于概率性响应,因此并不保证每次都返回我们理想中的那种“干净解释”。不过,在生产实现中,下面这些 warning 完全可以提升为 exception,从而直接中止流程:

WARNING:root:[Sanitizer] Potential threat detected with pattern: 'ignore any legal advice'
WARNING:root:[Researcher] A retrieved chunk failed sanitization and was skipped. Reason: Input sanitization failed. Potential threat detected.

在这里,我们故意只把它们保留在 warning 级别,是为了教学目的——便于观察玻璃盒 Context Engine 是如何运行的,以及我们如何识别那些“不符合预期”的结果。

现在,我们已经确认了引擎的诚实性。接下来,让我们再把它推向一个更模糊的地带。

自动化的边界:模糊请求(ambiguous request)

当一个请求并不明显超出范围,而只是模糊不清时,会发生什么?首先,把前一个目标(“Write a persuasive…”)注释掉,再取消注释下面这个:

# === CONTROL DECK 3 (LIMIT TEST): The Ambiguous Request ===
goal = "Analyze the attached NDA and draft a pleading based on its terms."

这是一种更隐蔽、也更危险的失败模式。pleading(诉状) 是一种格式高度刚性的法律文书。当 Librarian 去它的 blueprint library 中查找时,很可能根本找不到清晰匹配项。这个目标会让规划过程本身变得混乱,最终系统会报错:

ERROR:root:--- Executor: FATAL ERROR --- Execution failed at step 1 (Summarizer): Dependency Error: Reference USER_PROVIDED_NDA not found in state…

再一次,解决办法并不是写更多代码,而是组织设计。对于模糊请求这类头疼问题,一个现实可行的方案,是丰富上下文库(context library)。

在真实世界里,与法律团队的一次 workshop 往往会帮助我们识别出律所需要产出的所有关键文书类型。随后,团队与上下文工程师会一起构建一整套经过批准的 semantic blueprints,例如:

  • blueprint_for_pleading
  • blueprint_for_motion_to_dismiss
  • blueprint_for_cease_and_desist
  • ……

通过把引擎的 procedural capability 预定义且显式化,我们就能消除歧义,并确保每一种生成文书都遵循一种被认可、合规的法律结构。

Context Engine 只有在相关数据充分且流程明确定义时,才能稳定工作。否则,系统就会变得不稳定。从这些真实世界问题中,我们学到的根本教训是:上下文工程已经超出了 Context Engine 本身,而进入到了它所嵌入的整个生态系统。反过来,这个生态系统也会通过 Context Engine 被扩展。 换句话说,我们必须同时设计组织流程与引擎内部的 agentic process。

到这里,我们已经走了很长一段路,才让 Context Engine 真正变得通用,并在现实法律用例中验证它。

总结

在本章中,我们成功地把一个强大的推理系统,从一个有能力的原型,推进成了一个企业就绪型资产。而这绝不是一件轻松的事。我们直面了真实部署中的复杂性,为系统架构上必要的生产级防护措施做了设计。我们同时应对了性能与安全这两大挑战:一方面把系统延迟重新理解为一种为换取质量而做出的“刻意取舍”,另一方面也实现了一层不可谈判的内容审核护盾,以保护系统与用户。

为了证明系统已经成熟,我们把它演化成了一名法律合规助手,从而展示了它在领域层面无关性的灵活性。我们构建了一套稳健的双阶段审核协议,同时对用户输入和 AI 输出进行审查。接着,我们又把核心工作流重构成通用模板:高保真 RAG、上下文缩减,以及 grounded reasoning。现在,引擎已经拥有了一组可复用的通用模板。

我们还成功地将这些通用模板应用到了具有挑战性的法律用例中:从合同研究,到隐私政策摘要。

然而,这段旅程也同时暴露出:纯自动化方案的关键边界。 我们遇到了非常真实的头疼问题,在这些问题上,技术护栏本身也会失败——例如 sanitizer 会拦下合法法律证词,moderator 会标记那些其实有必要出现的脏话。这些障碍证明:复杂的上下文判断,往往不是靠更复杂的代码,而是靠组织规则来解决。

这也把我们带向了最终的架构洞见:最稳健的系统,会把业务逻辑与 AI 推理严格分离。 通过把那些确定性的组织规则放进策略驱动流程与系统中,我们定义出了一条清晰而安全的路径:让这台强大的 Context Engine,能够被集成进一个更大的企业生态之中。换句话说,我们已经成功把这台引擎准备成了一个能在真实世界、策略驱动型系统中可靠运行的组件。

下一章,我们将继续用市场营销用例,来检验这台通用 Context Engine。

问题

  • Context Engine 的延迟(慢)在文中是被描述为错误或低效的信号吗?(是或否)
  • 本章的安全协议是否建议只检查用户初始目标中的有害内容?(是或否)
  • helper_moderate_content 函数是否只返回一个简单的安全 / 不安全布尔值?(是或否)
  • execute_and_display 函数中,内容审核护栏是否默认始终开启?(是或否)
  • 本章是否得出结论:诸如法律文书中合法脏话这类“现实因子问题”,可以通过在 AI 引擎内部写更复杂代码来解决?(是或否)
  • 提出的元控制器是否被设计为处理复杂、非确定性的 AI 推理任务?(是或否)
  • 第 7 章中的 control decks 是否被重构得更“专门化”于法律领域?(是或否)
  • 针对法律用例,Data_Ingestion.ipynb 是否被从头重写来处理法律文档?(是或否)
  • 在测试系统边界时,helper_sanitize_input 是否正确处理了包含 “ignore any legal advice to the contrary” 的敌意证词?(是或否)
  • 当接收到“draft a pleading”这种模糊目标时,引擎是否成功生成了一份法律上有效的文书?(是或否)

参考文献

Shu, R., Das, N., Yuan, M., Sunkara, M., & Zhang, Y. (2024). Towards Effective GenAI Multi-Agent Collaboration: Design and Evaluation for Enterprise Applications. arXiv preprint arXiv:2412.05449.

Palla, K., Redondo García, J. L., Hauff, C., Fabbri, F., Lindström, H., Taber, D. R., Damianou, A., & Lalmas, M. (2025). Policy-as-Prompt: Rethinking Content Moderation in the Age of Large Language Models. arXiv preprint arXiv:2502.18695.

延伸阅读

Hou, Z., Ye, Z., Zeng, N., Hao, T., & Zeng, K. (2025). Large Language Models Meet Legal Artificial Intelligence: A Survey. arXiv preprint arXiv:2509.09969.