上下文隔离与预算分配
正在读取学习记录…
上下文是某位Agent这一次处理任务时能看到的目标、限制、资料和历史。上下文隔离让不同角色只拿到自己需要且有权使用的内容。预算分配则在可见资料中,决定哪些信息必须保留、哪些可以省略。
先按客户归属和角色权限筛选资料,再按长度预算挑选。这样留下的每一项资料都有明确的访问范围,也能解释哪些内容因额度不足被略去。
主管不必把整个聊天记录群发。查订单的执行者需要订单与发货状态,计划者可能需要业务规则和已确认金额;每个人都读全套,不仅费钱,也容易被无关内容带偏。
一笔退款任务,两份不同资料包
任务目标是核查O-17退款资格,限制是禁止直接付款。它们构成必须信息,预先占3个估算单位。
资料表包含共享规则、shop-A的订单与库存、shop-B的另一个客户订单。每项记录都标明租户、可见角色、估算占用和优先级。租户是数据归属的业务空间,例如不同商家。
planner即计划者,在12单位内看到规则5与订单4,加上目标3,正好用满12。executor即执行者看到订单4与库存5,也用满12。另一客户资料即使只有3单位,也不会为了“凑满预算”混进来。这里的单位是预置的长度估算,真实模型请求需要用所选模型的分词器与消息开销核算token。
保存完整程序并运行
在自己的学习目录打开PowerShell,创建一个新的子目录:
mkdir l6-context
cd l6-context把下面完整代码保存为 context_demo.py。固定数据和运行入口都已包含,文件名保留 .py 后缀。
"""按角色和租户构造受预算约束的资料包。"""
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,再运行:
ls
python -X utf8 context_demo.py程序输出:
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单位都放不下,程序直接拒绝构造资料包,而不是为了运行成功删掉限制。
可选资料也可能对某个判断必不可少。例如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
"""检查权限筛选先于预算截断,必须信息不会被挤走。"""
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()python -X utf8 -m unittest -v test_context_demo.py测试名称后应显示 ok,末尾显示 Ran 5 tests 和 OK。若找不到模块,先用 dir 确认两个文件保存在同一目录。
课后练习展开习题收起习题
正在读取本地记录…
不调用模型,不执行代码。简答、代码和场景题仅保存答案并展示自查标准,不生成评分、徽章或认证。输入内容不会自动保存,请点击提交;不要填写个人信息或密钥。
选择题 · 订单执行者完成任务通常最需要哪些上下文
订单执行者完成任务通常最需要哪些上下文?
对应知识点:L6-context
简答题 · 解释机制
怎样同时表达角色隔离和容量限制?
对应知识点:L6-context
代码题 · 核对给定数据
资料长度分别为4、3、5,预算7。写断言检查前两项恰好可放入。
对应知识点:L6-context
场景题 · 分析具体变化
汇总者缺少订单金额,但预算已满,应怎样整理资料?
对应知识点:L6-context
描述会发送给本站维护者,用于修订文章,保存90天。请只填写文章问题,省略个人信息、密钥和内部资料。