AgentDepthAgent 工程学习指南
输入概念或问题,检索正文和待编写目录。
第一次学习?从 L0 总览开始 →

上下文隔离与预算分配

我的学习 →

正在读取学习记录…

上下文是某位Agent这一次处理任务时能看到的目标、限制、资料和历史。上下文隔离让不同角色只拿到自己需要且有权使用的内容。预算分配则在可见资料中,决定哪些信息必须保留、哪些可以省略。

先按客户归属和角色权限筛选资料,再按长度预算挑选。这样留下的每一项资料都有明确的访问范围,也能解释哪些内容因额度不足被略去。

主管不必把整个聊天记录群发。查订单的执行者需要订单与发货状态,计划者可能需要业务规则和已确认金额;每个人都读全套,不仅费钱,也容易被无关内容带偏。

一笔退款任务,两份不同资料包

任务目标是核查O-17退款资格,限制是禁止直接付款。它们构成必须信息,预先占3个估算单位。

资料表包含共享规则、shop-A的订单与库存、shop-B的另一个客户订单。每项记录都标明租户、可见角色、估算占用和优先级。租户是数据归属的业务空间,例如不同商家。

planner即计划者,在12单位内看到规则5与订单4,加上目标3,正好用满12。executor即执行者看到订单4与库存5,也用满12。另一客户资料即使只有3单位,也不会为了“凑满预算”混进来。这里的单位是预置的长度估算,真实模型请求需要用所选模型的分词器与消息开销核算token。

保存完整程序并运行

在自己的学习目录打开PowerShell,创建一个新的子目录:

Bash
mkdir l6-context
cd l6-context

把下面完整代码保存为 context_demo.py。固定数据和运行入口都已包含,文件名保留 .py 后缀。

Python
"""按角色和租户构造受预算约束的资料包。"""
from dataclasses import dataclass

@dataclass(frozen=True)
class Record:
    id: str
    tenant: str
    roles: frozenset
    estimate: int
    priority: int
    text: str

RECORDS = [
    Record("policy", "shared", frozenset({"planner", "reviewer"}), 5, 1, "未发货可退已付金额"),
    Record("order", "shop-A", frozenset({"planner", "executor"}), 4, 2, "O-17已付120元"),
    Record("stock", "shop-A", frozenset({"executor"}), 5, 3, "O-17尚未发货"),
    Record("other-customer", "shop-B", frozenset({"executor"}), 3, 1, "另一客户订单"),
]
GOAL = {"text": "核查O-17退款资格;禁止直接付款", "estimate": 3}

def build_context(role, tenant, budget, records=RECORDS):
    if type(budget) is not int or budget < GOAL["estimate"]:
        raise ValueError("预算不足以容纳目标和限制")
    selected, used, skipped = [], GOAL["estimate"], []
    visible = sorted((row for row in records
                      if row.tenant in {tenant, "shared"} and role in row.roles),
                     key=lambda row: (row.priority, row.id))
    # 必须信息先占额度,可选资料只能使用剩余空间。
    for row in visible:
        if used + row.estimate <= budget:
            selected.append(row)
            used += row.estimate
        else:
            skipped.append(row.id)
    return {"goal": GOAL["text"], "records": selected, "used": used, "skipped": skipped}

def show(role, budget):
    package = build_context(role, "shop-A", budget)
    ids = ",".join(row.id for row in package["records"]) or "无"
    skipped = ",".join(package["skipped"]) or "无"
    return f"{role}:资料={ids};估算额度={package['used']}/{budget};因预算略去={skipped}"

def main():
    print(show("planner", 12))
    print(show("executor", 12))
    print(show("executor", 7))
    print("必须信息:" + GOAL["text"])
    has_other = any(row.id == "other-customer" for row in build_context("executor", "shop-A", 1000)["records"])
    print("隔离检查:shop-A资料包" + ("含有" if has_other else "没有") + "other-customer")

if __name__ == "__main__":
    main()

保存后执行 dir,确认能看到 context_demo.py,再运行:

Bash
ls
python -X utf8 context_demo.py

程序输出:

TXT
planner:资料=policy,order;估算额度=12/12;因预算略去=无
executor:资料=order,stock;估算额度=12/12;因预算略去=无
executor:资料=order;估算额度=7/7;因预算略去=stock
必须信息:核查O-17退款资格;禁止直接付款
隔离检查:shop-A资料包没有other-customer

先筛资料,后用剩余额度装进去

Record中的tenant表示业务归属,roles表示允许看到它的角色。build_context先同时检查这两项。只有属于当前租户或共享范围、并且包含当前角色的资料,才进入visible列表。

随后按priority和id稳定排序。priority数字越小越先装入;id用于相同优先级时保持确定顺序。used从GOAL的3开始,逐条判断加入资料后是否超预算。

预算为7时,执行者仍保留目标3和订单4,库存5放不下,进入skipped。被略去的是可见但超预算的资料;越权资料从未进入候选,因此也不会以“略去的资料标题”泄露给处理者。

资料先按租户和角色筛选,再保留3单位目标限制,计划者获取规则和订单,执行者获取订单和库存
隔离决定有权看什么,预算决定可见内容能放多少;资料包构造成功还需检查业务证据是否充分。

把目标与证据分开,才能判断信息是否足够

目标与禁止付款属于不可省略的约束。若连这3单位都放不下,程序直接拒绝构造资料包,而不是为了运行成功删掉限制。

可选资料也可能对某个判断必不可少。例如executor缩到7后只有订单金额,缺库存与发货状态,就不足以决定是否符合“未发货可退”。构造成功表示包符合权限与预算,不表示业务证据完整。执行者应请求补充资料或报告缺失,不能把skipped解释成“默认未发货”。

真实应用可以给某些证据标记必需项,先做可执行性检查,再装可选项。若关键规则和订单资料无法同时放入,改用短而可核对的结构字段,或拆成两个明确的子任务;不要无声删除一项关键条件。

为什么全量共享未必更可靠

一位Agent的搜索记录、工具报错和未确认猜测,未必都是另一位Agent需要的事实。把这些内容全部转发,可能浪费额度,也可能把过时建议变成后续处理者的默认前提。

移交包适合包含目标、已确认事实、待补事项、依据引用及允许动作。压缩摘要应保留订单编号、金额、规则版本等会改变决策的字段。结果短一些不是唯一目标,接手者能否据此作正确判断更重要。

隔离也不是把处理者之间的联系完全切断。共同目标和必要的依赖产物需要共享;内部草稿和与任务无关的客户资料可以独立。通过来源编号传递可检索证据,通常比复制整段工具日志更容易核对。

上下文额度与团队总额度怎样关联

每个角色都有上下文额度,团队仍需一个总消耗上限。四位Agent各拿到12单位,并不表示团队只消耗12;资料重复传输、回复和汇总也会占用量。

上下文额度限制一次请求能容纳多少信息,调用次数与输出上限限制整项任务的消耗。并行运行只缩短部分等待时间,不会让重复上下文免费。实际分配时,应先确认任务拆分的价值,再给各角色设置与职责相匹配的额度。

缩小预算,观察具体丢了什么

把main第一行show("planner", 12)改为show("planner", 8),运行python -X utf8 context_demo.py。计划者保留目标3和规则5,订单进入skipped,显示“资料=policy;估算额度=8/8;因预算略去=order”。

再把执行者的7改成2,运行同一命令,程序报“预算不足以容纳目标和限制”。若调回12,也不会得到other-customer;这是权限筛选决定的,增加预算不能越过数据归属。

结束时将计划者第一处show恢复为12,将执行者第三处show恢复为7,保存并运行。正常输出重新包含两份12单位资料包和一份缺库存的7单位资料包,再运行配套检查。

参考阅读:LangChain Subagents重点看上下文隔离和返回产物;Anthropic多Agent研究系统阅读各角色任务分配与信息传递的工程安排。

运行配套检查

把下面测试完整保存为 test_context_demo.py,与主程序放在同一目录。5项检查覆盖角色不同视图、跨租户排除、预算裁剪、必须信息门禁和无资料权限的角色。

查看测试代码:test_context_demo.py
Python
"""检查权限筛选先于预算截断,必须信息不会被挤走。"""
import sys
import unittest
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import context_demo as demo

class ContextTests(unittest.TestCase):
    def test_planner_and_executor_have_different_views(self):
        planner = demo.build_context("planner", "shop-A", 12)
        executor = demo.build_context("executor", "shop-A", 12)
        self.assertEqual([x.id for x in planner["records"]], ["policy", "order"])
        self.assertEqual([x.id for x in executor["records"]], ["order", "stock"])

    def test_other_tenant_never_enters_even_with_large_budget(self):
        package = demo.build_context("executor", "shop-A", 1000)
        self.assertNotIn("other-customer", [x.id for x in package["records"]])

    def test_small_budget_preserves_goal_and_skips_stock(self):
        package = demo.build_context("executor", "shop-A", 7)
        self.assertEqual(package["goal"], demo.GOAL["text"])
        self.assertEqual(package["used"], 7)
        self.assertEqual(package["skipped"], ["stock"])

    def test_budget_below_mandatory_is_rejected(self):
        for budget in (2, True, 1.5):
            with self.subTest(budget=budget), self.assertRaises(ValueError):
                demo.build_context("planner", "shop-A", budget)

    def test_role_without_access_only_gets_goal(self):
        package = demo.build_context("writer", "shop-A", 12)
        self.assertEqual(package["records"], [])
        self.assertEqual(package["used"], 3)

if __name__ == "__main__":
    unittest.main()
Bash
python -X utf8 -m unittest -v test_context_demo.py

测试名称后应显示 ok,末尾显示 Ran 5 tests 和 OK。若找不到模块,先用 dir 确认两个文件保存在同一目录。

课后练习展开习题收起习题

4 道练习 · 客观题规则评分 · 其余题目待批改

正在读取本地记录…

不调用模型,不执行代码。简答、代码和场景题仅保存答案并展示自查标准,不生成评分、徽章或认证。输入内容不会自动保存,请点击提交;不要填写个人信息或密钥。

练习 1 / 4 · v1.1.0

选择题 · 订单执行者完成任务通常最需要哪些上下文

订单执行者完成任务通常最需要哪些上下文?

对应知识点:L6-context

选择一个答案
练习 2 / 4 · v1.1.0

简答题 · 解释机制

怎样同时表达角色隔离和容量限制?

对应知识点:L6-context

练习 3 / 4 · v1.1.0

代码题 · 核对给定数据

资料长度分别为4、3、5,预算7。写断言检查前两项恰好可放入。

对应知识点:L6-context

练习 4 / 4 · v1.1.0

场景题 · 分析具体变化

汇总者缺少订单金额,但预算已满,应怎样整理资料?

对应知识点:L6-context

图片查看器
100%

文章配图 · 按 Esc 关闭