
流程驱动架构中的Agent并非单次调用即可完成任务的简单对话系统。它需要在多节点、多分支、可能经历分裂与合并的长周期流程中,持续做出正确决策。而所有决策的基础——上下文(Context),恰恰是整个体系中最脆弱、最易失控的环节。上下文治理不是锦上添花的优化,而是流程驱动Agent能否可靠运行的生存性问题。
在流程驱动的Agent中,一次业务流程可能包含10~50个活动节点,每个节点产生若干轮对话。即使以每轮平均200 token计算,一个20节点的流程就能产生8000+ token的历史上下文。当流程包含并行分支时,膨胀速度呈指数级增长。
核心矛盾LLM的上下文窗口是有限共享资源。不加治理的上下文注入等同于全局变量污染 —— 随着流程复杂度增长,Agent行为将变得不可预测,且token成本线性失控。
具体表现为:
TokenTotal(N) = |SYSTEM| + |PROCESS| + Σi=1..N(|Activityi_history| + |Activityi_knowledge|) + |WORKING| + |TOOLS|
上下文污染比膨胀更为隐蔽和危险。膨胀只是"多了",而污染是"错了"——无关的信息干扰了当前的决策。
污染的隐蔽性上下文污染往往不会导致明显的运行时错误,而是让LLM在看似正确的上下文中做出微妙错误的决策。这类问题极难通过测试发现,却可能在生产环境中引发业务逻辑错误。
流程的分裂(XOR_SPLIT / PARALLEL_SPLIT)和合并(XOR_JOIN / AND_JOIN)是上下文丢失的高发区:
即使上下文没有膨胀到超限,过多的冗余信息也会导致LLM的注意力稀释:
治理目标上下文治理的核心目标:在任何流程状态下,为LLM提供精确且最小充分的上下文 —— 包含所有必要信息,不包含任何冗余/污染信息,关键信息处于注意力高位。
这四个挑战并非独立存在,而是相互耦合的:膨胀导致注意力分散,污染加剧丢失风险,丢失迫使保留更多历史(加剧膨胀)。治理必须是系统性的,局部优化无法解决全局问题。下文的六层架构和三大决策点正是为系统性治理而设计。
上下文治理的第一步是分层。正如操作系统将内存分为内核空间/用户空间/交换区,流程驱动Agent需要将上下文分为不同生命周期、不同访问权限、不同持久化策略的层级。分层使得每一层可以被独立治理——独立压缩、独立分裂、独立合并。

层级 | 名称 | 内容类型 | 写入权限 | 持久化 | 分裂行为 |
|---|---|---|---|---|---|
L0 | SYSTEM | 系统提示词、角色定义、安全约束 | 只读 | 永久 | 共享(不复制) |
L1 | PROCESS | 流程定义、流程变量、全局配置 | 只读+追加 | 流程实例生命周期 | 共享(引用) |
L2 | KNOWLEDGE | 领域知识、业务规则、RAG结果 | 读+写 | 流程实例+知识库 | 继承(深拷贝+增量) |
L4 | HISTORY | 决策摘要、状态变更、压缩历史 | 只读+压缩 | 流程实例(可降级DB) | 各分支独立 |
L4 | WORKING | 当前活动状态、待决策参数 | 读+写+清理 | 活动实例 | 深拷贝+分支注入 |
L5 | EPHEMERAL | 临时变量、工具返回缓冲 | 读+写 | 无(内存) | 不参与 |
六层不是孤立的,它们之间存在严格的交互规则,确保信息流动的有序性和可控性:
当LLM需要获取某个key的值时,按L0→L1→L2→L3→L4→L5的顺序查找,首次命中即返回。这保证了系统级定义不可被覆盖,同时允许活动级变量覆盖流程级变量(同名key场景)。
分层的核心价值分层将"全局变量"式的混沌上下文转变为"作用域限定"的结构化上下文。每一层可以独立实施压缩策略、独立进行分裂/合并处理,使得治理从"一刀切"变为"精准手术"。
上下文治理的三个核心决策点,分别对应上下文生命周期中的三个关键转换时刻。每个决策点都需要在规则引擎和LLM推理之间取得平衡——纯规则驱动缺乏灵活性,纯LLM驱动缺乏可控性。

压缩决策发生在活动完成或上下文超限时,决定哪些信息从WORKING层迁移到HISTORY层、以何种形式迁移。这是最频繁触发的决策点,直接决定上下文的"新陈代谢"效率。
分裂决策发生在流程网关分叉时,决定每个分支获得哪些上下文、如何获得。这决定了分支间是"共享视野"还是"独立视野",直接影响并行执行的正确性。
合并决策发生在流程网关汇聚时,决定如何将多个分支的上下文合并为统一视图。当不同分支对同一key写入了不同值时,冲突不可避免,合并决策决定"谁是权威"。
决策点的设计原则每个决策点都遵循规则优先、LLM辅助、HUMAN兜底的三级模式:规则引擎处理确定场景,LLM处理模糊场景,HUMAN处理关键场景。三级之间的切换由可配置的阈值和策略控制。
压缩是上下文治理中最具技术深度的环节。它不是简单的"删除旧消息",而是在保留决策可追溯性的前提下,最大化减少token占用。好的压缩让LLM既能回溯"为什么做出那个决策",又不需要看到"做决策时的全部原始信息"。
压缩的触发不是单一的"超限就压",而是多维度的综合判断:
即使未达到token阈值,如果LLM的注意力质量下降,也应触发压缩。注意力检测包含5个维度:
维度 | 检测方法 | 阈值 | 含义 |
|---|---|---|---|
关键信息密度 | 关键token数 / 总token数 | < 0.15 | 关键信息被淹没 |
信息冗余度 | 重复/相似内容占比 | > 0.3 | 大量冗余消耗注意力 |
时序衰减度 | 最近N轮信息的注意力权重占比 | < 0.6 | 最新信息未获足够关注 |
语义冲突度 | 矛盾信息的检出率 | > 0.05 | 存在互相矛盾的上下文 |
工具调用效率 | 有效工具返回 / 总工具调用 | < 0.5 | 大量无效工具调用占用空间 |
CompressTrigger = (TokenExceed ∨ MsgExceed ∨ ActivityExceed) ∨ (AttnDensity<0.15 ∨ Redundancy>0.3 ∨ Decay<0.6 ∨ Conflict>0.05 ∨ ToolEff<0.5)
规则驱动压缩是第一道防线,处理确定性的压缩场景,无需LLM参与:
每个活动可配置preserveKeys列表,这些key对应的值在压缩时无条件保留,即使压缩到极致也不删除。
{
"activityId": "risk_assessment",
"preserveKeys": [
"risk_level", // 风险等级 — 后续审批依赖
"assessment_id", // 评估ID — 审计追踪
"risk_factors" // 风险因子 — 决策解释
]
}将HISTORY中的原始消息替换为结构化摘要:
{
"compressRules": [
{
"pattern": "tool_call_result",
"action": "extract_keys",
"extractKeys": ["status", "data.id", "data.summary"]
},
{
"pattern": "reasoning_chain",
"action": "summarize",
"maxTokens": 100
},
{
"pattern": "error_retry_log",
"action": "count_only",
"keepLast": 1
}
]
}当规则驱动压缩无法满足需求时(如需要理解语义重要性),LLM参与压缩决策:
LLM通过工具链参与压缩,遵循检查→评估→压缩的流程:
你是一个上下文压缩决策引擎。当前上下文状态:
- HISTORY层: {token_count} tokens, {key_count} keys
- WORKING层: {token_count} tokens, {key_count} keys
- 注意力评分: 密度={density}, 冗余={redundancy}
必须保留的key: {preserve_keys}
当前活动需要的上下文: {required_context}
请决定:
1. 哪些已完成活动的上下文可以压缩为摘要?
2. 摘要应保留哪些关键信息点?
3. 哪些上下文可以完全移除?
输出JSON格式的压缩计划。当流程执行超过一定数量的活动后,HISTORY层本身也需要压缩。二次压缩将多个活动的HISTORY摘要进一步合并为流程级摘要:

分裂决策决定了流程分叉时每个分支的上下文起点。它不是简单的"全量复制",而是根据各层的语义特性,选择最适合的分裂策略。错误的分裂策略会导致:分支间不该共享的信息泄露(污染)、或该共享的信息缺失(丢失)。
六层架构中,每一层在分裂时有不同的策略,这些策略由层的语义和生命周期决定:
层级 | 分裂策略 | 原因 | 实现 |
|---|---|---|---|
L0SYSTEM | 共享 | 系统定义是全局不变的,所有分支必须遵守同一套规则 | 引用传递,不复制 |
L1PROCESS | 共享 | 流程定义和流程变量对所有分支可见且一致 | 引用传递,不复制 |
L2KNOWLEDGE | 继承 | 分支需要基线知识,但可能各自发现新知识 | 深拷贝基线 + 增量独立 |
L3HISTORY | 独立 | 各分支的历史是各自发生的,不应互相可见 | 深拷贝,各自累积 |
L4WORKING | 深拷贝+分支注入 | 需要当前状态+分支特定条件 | 深拷贝 + 注入分支条件变量 |
L5EPHEMERAL | 不参与 | 临时变量不跨活动,分裂时已无意义 | 清空,不传递 |

XOR_SPLIT网关的分支选择通常是条件表达式,但在业务场景中,分支条件可能是自然语言描述的,而非结构化表达式。此时需要LLM参与分支条件判断:
// Designer定义的分支条件(自然语言)
{
"gatewayId": "approval_split",
"type": "XOR_SPLIT",
"branches": [
{
"id": "fast_track",
"condition": "如果风险等级为低且金额小于5万,走快速通道",
"contextInject": { "track_type": "fast", "requires_approval": false }
},
{
"id": "full_review",
"condition": "其他情况走完整审核流程",
"contextInject": { "track_type": "full", "requires_approval": true }
}
]
}LLM在分裂时读取当前WORKING层的risk_level和amount,结合自然语言条件,决定进入哪个分支,并将contextInject注入到分支的WORKING层。
分裂后,系统需要评估分支的上下文质量,确保每个分支具备足够信息完成后续活动。评估算法基于三个维度:
BranchQuality = α × KeyCoverage + β × ValueConsistency + γ × KnowledgeConfidence
当BranchQuality < qualityThreshold时,触发上下文补全:从KNOWLEDGE层检索缺失知识、从HISTORY层提取相关历史、必要时触发human_confirm请求补充信息。
合并决策是上下文治理中冲突最密集的环节。当多个并行分支各自修改了上下文后汇聚,合并决策需要解决"谁说了算"的问题。与Git的merge冲突类似,但更复杂——因为上下文是结构化的、语义的,不是纯文本的。
合并时的冲突检测采用逐key比较策略,以分裂前的快照为基准(base),比较各分支的修改:
function detectConflicts(base, branches):
conflicts = []
allKeys = union(branches.map(b => b.keys()))
for key in allKeys:
baseValue = base.get(key)
branchValues = branches.map(b => b.get(key))
uniqueValues = distinct(branchValues.filter(v => v != baseValue))
if uniqueValues.length > 1:
// 多个分支对同一key写入了不同值 → 冲突
conflicts.append({
key: key,
baseValue: baseValue,
conflictingValues: uniqueValues,
sourceBranches: branches.filter(b => b.get(key) in uniqueValues)
})
else if uniqueValues.length == 1 and baseValue != uniqueValues[0]:
// 仅一个分支修改,且与基准不同 → 无冲突,采用修改值
markAsModified(key, uniqueValues[0])
return conflicts检测结果写入_mergedConflicts字段,供后续冲突解决使用:
{
"_mergedConflicts": [
{
"key": "approval_status",
"baseValue": "pending",
"conflictingValues": ["approved", "rejected"],
"sourceBranches": ["branch_finance", "branch_risk"],
"resolution": null // 待解决
}
]
}策略 | 冲突处理 | 适用场景 | 风险 |
|---|---|---|---|
MERGE_WITH_CONFLICT_DETECT | 检测冲突,标记到_mergedConflicts,由LLM或HUMAN解决 | 分支间存在语义关联(如审批结果影响后续决策) | 需要额外的解决步骤,可能阻塞流程 |
LAST_WRITE_WINS | 最后一个完成的分支的值覆盖其他分支 | 分支间无语义关联,只需最新状态 | 可能丢失重要信息 |
PRESERVE_ALL_BRANCHES | 所有分支的值都保留,key加上分支前缀 | 需要保留所有分支结果供后续选择 | key爆炸,需要后续选择逻辑 |
当合并策略为MERGE_WITH_CONFLICT_DETECT且存在未解决的冲突时,LLM参与冲突解决:
你是一个上下文合并冲突解决引擎。以下是合并冲突:
冲突Key: approval_status
- 基准值: pending
- 分支finance的值: approved (原因: 财务审核通过,金额在授权范围内)
- 分支risk的值: rejected (原因: 风险评估发现异常交易模式)
相关上下文:
- 金额: 120,000
- 风险等级: high
- 公司政策: 高风险+高金额需要双重审批
请决定:
1. 最终值应该是什么?
2. 决策依据是什么?
3. 是否需要升级为HUMAN确认?
输出JSON格式的冲突解决结果。
合并冲突检测的准确度高度依赖于分裂前的基准快照。系统在每次分裂时自动保存快照:
{
"_splitSnapshot": {
"snapshotId": "snap_20260708_001",
"splitGatewayId": "parallel_review",
"timestamp": "2026-07-08T10:30:00Z",
"context": {
"L0": "<reference>",
"L1": "<reference>",
"L2": { /* 深拷贝 */ },
"L3": { /* 深拷贝 */ },
"L4": { /* 深拷贝 */ }
},
"branchIds": ["branch_finance", "branch_risk", "branch_compliance"]
}
}快照的必要性没有基准快照,合并时只能做"各分支互相比较",无法判断哪个分支修改了值、哪个分支保持不变。基准快照使得冲突检测从O(N²)的分支间比较降为O(N)的分支-基准比较,且能区分"新增"和"修改"两种不同的变更类型。
上下文治理中,并非所有决策都能由规则或LLM完成。关键场景需要人类干预——不是事后审查,而是实时介入。HUMAN回路将人类从"旁观者"变为"治理者",提供4种触发入口和16个干预选项。
触发类型 | 时机 | 典型场景 | 干预方式 |
|---|---|---|---|
设计时 | Designer配置流程时 | 定义压缩策略、合并策略、知识注入规则 | ActivityExtensionConfig预设 |
运行时 | 流程执行过程中 | 上下文异常、压缩效果不佳、分支选择犹豫 | Chat侧干预面板 |
质量 | 质量检查不通过时 | 合并冲突未解决、知识置信度不足、分支评估失败 | 自动触发+人工确认 |
冲突 | 合并时检测到冲突 | 多分支对同一key值不一致 | 冲突解决面板 |
干预选项按治理领域分为4组:
# | 选项 | 说明 | 适用触发 |
|---|---|---|---|
C1 | 手动压缩 | 选择特定层/特定key执行压缩 | 运行时 |
C2 | 锁定key | 将key加入PRESERVE_KEYS,禁止压缩 | 设计时/运行时 |
C3 | 注入上下文 | 手动向指定层写入key-value | 运行时 |
C4 | 清理污染 | 移除指定key或层中的过期数据 | 运行时 |
C5 | 调整阈值 | 修改压缩/注意力检测的阈值参数 | 设计时/运行时 |
# | 选项 | 说明 | 适用触发 |
|---|---|---|---|
K1 | 注入知识 | 向KNOWLEDGE层添加领域知识 | 设计时/运行时 |
K2 | 提升置信度 | 手动确认知识的正确性,提升其置信度 | 质量 |
K3 | 标记废弃 | 将过期知识标记为deprecated | 运行时 |
K4 | 知识重检索 | 触发RAG重新检索,替换低置信度知识 | 质量 |
# | 选项 | 说明 | 适用触发 |
|---|---|---|---|
P1 | 切换分支 | 在XOR_SPLIT时手动选择分支 | 运行时 |
P2 | 合并策略覆盖 | 运行时修改合并策略 | 冲突 |
P3 | 冲突仲裁 | 手动选择冲突key的最终值 | 冲突 |
P4 | 回退 | 回退到分裂前快照,重新执行分支 | 运行时/冲突 |
# | 选项 | 说明 | 适用触发 |
|---|---|---|---|
L1 | 强制LLM压缩 | 绕过规则,强制LLM执行压缩 | 运行时 |
L2 | 修改Prompt | 调整LLM的决策prompt模板 | 设计时 |
L3 | 切换模型 | 为特定决策切换到更强/更弱的模型 | 运行时 |

在Designer中,用户通过ActivityExtensionConfig为每个活动预设上下文治理规则。这些规则在流程定义时确定,运行时自动生效:
// ActivityExtensionConfig 示例
{
"activityId": "risk_assessment",
"contextStrategy": {
"preserveKeys": ["risk_level", "assessment_id"],
"compressRules": [
{ "pattern": "tool_call_result", "action": "extract_keys" }
],
"compressTokenThreshold": 4000,
"attentionThresholds": {
"density": 0.15, "redundancy": 0.3
}
},
"mergeStrategy": "MERGE_WITH_CONFLICT_DETECT",
"knowledgeConfig": {
"ragCollections": ["risk_kb", "policy_kb"],
"confidenceThreshold": 0.7
}
}Chat侧提供ContextGovernanceController REST端点,支持运行时实时干预:
// REST端点
POST /api/context-governance/inspect // 查看上下文状态
POST /api/context-governance/compress // 手动触发压缩
POST /api/context-governance/inject // 注入上下文
POST /api/context-governance/resolve // 冲突仲裁
POST /api/context-governance/rollback // 回退到快照
POST /api/context-governance/config // 运行时修改配置双端治理闭环Designer侧的预设规则是"默认策略",Chat侧的运行时干预是"实时调整"。两者形成闭环:运行时干预的经验可以反馈到Designer,更新预设规则(知识飞轮的一部分)。
LLM在上下文治理中的参与不是直接操作内存,而是通过工具调用(Tool Use)实现。每个工具封装了特定的治理操作,LLM通过决策决定调用哪些工具、传入什么参数。这种设计确保了LLM的治理行为是可审计、可回滚、可限流的。
检查指定层的内容和统计信息,是所有治理决策的起点:
context_inspect({
layers: ["L3", "L4"], // 检查HISTORY和WORKING层
metrics: [ // 请求的统计指标
"token_count", // 每层token数
"key_count", // 每层key数
"attention_score", // 注意力评分(5维)
"last_modified", // 最后修改时间
"size_bytes" // 内存占用
],
filter: { // 可选过滤条件
"key_prefix": "risk_*", // 只检查risk开头的key
"modified_after": "2026-07-08T10:00:00Z"
}
})
// 返回
{
"L3": {
"token_count": 3200,
"key_count": 18,
"attention_score": { "density": 0.12, "redundancy": 0.35 },
"keys": ["risk_level", "assessment_id", ...]
},
"L4": {
"token_count": 800,
"key_count": 6,
"attention_score": { "density": 0.45, "redundancy": 0.1 }
}
}执行压缩/解压/评估操作:
// 执行压缩
context_compress({
action: "compress",
target_layers: ["L3"],
preserve_keys: ["risk_level", "assessment_id", "risk_factors"],
compress_rules: [
{ pattern: "tool_call_result", action: "extract_keys", extractKeys: ["status", "summary"] },
{ pattern: "reasoning_chain", action: "summarize", maxTokens: 100 }
],
max_tokens: 2000
})
// 评估压缩效果
context_compress({
action: "evaluate",
before_snapshot_id: "snap_before_compress"
})
// 解压(回退压缩)
context_compress({
action: "decompress",
snapshot_id: "snap_before_compress"
})分支评估、冲突解决、快照操作:
// 分支评估
context_branch({
action: "evaluate",
branch_id: "branch_finance",
required_keys: ["amount", "approval_status"]
})
// 冲突解决
context_branch({
action: "resolve_conflict",
conflict_key: "approval_status",
resolution: "approved",
reason: "财务审核通过优先,风险问题后续处理"
})
// 创建快照
context_branch({
action: "snapshot",
layers: ["L2", "L3", "L4"]
})HUMAN确认工具,当LLM判断需要人类介入时调用:
human_confirm({
type: "conflict_resolution",
message: "分支finance和risk对approval_status存在冲突,请选择最终值",
options: [
{ label: "采用approved(财务审核通过)", value: "approved" },
{ label: "采用rejected(风险评估拒绝)", value: "rejected" },
{ label: "升级为双人审批", value: "escalate" }
],
timeout: 300 // 5分钟超时
})以下展示一个完整的压缩决策工具调用序列:
┌─ LLM调用序列:压缩决策 ─────────────────────────────┐
│ │
│ 1. context_inspect(layers=["L3","L4"], │
│ metrics=["token_count","attention_score"]) │
│ → L3: 3200 tokens, density=0.12 │
│ → L4: 800 tokens, density=0.45 │
│ │
│ 2. [LLM判断] L3密度<0.15 → 触发压缩 │
│ │
│ 3. context_compress(action="compress", │
│ target_layers=["L3"], │
│ preserve_keys=["risk_level","assessment_id"], │
│ max_tokens=1500) │
│ → 压缩完成: 3200→1350 tokens │
│ │
│ 4. context_compress(action="evaluate", │
│ before_snapshot_id="snap_xxx") │
│ → 密度提升: 0.12→0.38, 关键key全部保留 │
│ │
│ 5. [LLM判断] 压缩效果良好,无需human_confirm │
│ │
└───────────────────────────────────────────────────────┘
上下文治理不是通用方案,每个业务场景的压缩策略、合并策略、知识需求都不同。ActivityExtensionConfig提供了6维配置能力,结合Designer侧的扩展面板和Chat侧的运行时看板,实现可定制、可观测、可干预的治理体系。
维度 | 配置项 | 默认值 | 说明 |
|---|---|---|---|
上下文策略 | contextStrategy | PRESERVE_KEYS=[] | 保留key、压缩规则、阈值配置 |
压缩策略 | compressStrategy | RULE_FIRST | RULE_FIRST / LLM_ASSISTED / LLM_DRIVEN |
合并策略 | mergeStrategy | MERGE_WITH_CONFLICT_DETECT | 三种合并策略选择 |
知识配置 | knowledgeConfig | RAG=[] | RAG集合、置信度阈值、知识飞轮开关 |
HUMAN回路 | humanLoopConfig | auto=false | 哪些决策需要HUMAN确认、超时策略 |
分支策略 | branchStrategy | default | 分裂时的层策略覆盖、分支条件注入 |
在Designer的活动属性面板中,增加上下文治理扩展区域,分为三个Tab:

Chat侧的运行时看板提供上下文治理的实时可视化,帮助用户理解当前状态、发现问题、执行干预:
Designer侧和Chat侧通过ContextGovernanceDTO共享上下文治理状态:
class ContextGovernanceDTO {
// 层大小信息
Map<String, LayerInfo> layerInfos; // L0~L5各层统计
// 压缩状态
CompressStatus compressStatus; // 压缩状态/历史/阈值
// 注意力评分
AttentionScore attentionScore; // 5维注意力评分
// 知识评分
List<KnowledgeScore> knowledgeScores; // 知识置信度列表
// 冲突信息
List<MergedConflict> mergedConflicts; // 待解决冲突
// 分支信息
List<BranchInfo> branchInfos; // 各分支状态
// 配置快照
ActivityExtensionConfig activeConfig; // 当前生效的配置
}
class LayerInfo {
String layerId; // L0~L5
int tokenCount;
int keyCount;
long sizeBytes;
long lastModified;
List<String> topKeys; // 占比最高的key
}双端模型的一致性ContextGovernanceDTO是Designer和Chat之间的共享契约。Designer写入配置(ActivityExtensionConfig),Chat读取运行时状态(LayerInfo/AttentionScore等)。两者通过REST端点同步,确保"所见即所治"。
设计不是空中楼阁,每个设计点都需要有对应的代码实现。以下对照表将本文的每个关键设计点映射到具体的代码文件、决策知识文件和REST端点。
设计点 | 实现文件 | 关键类/方法 |
|---|---|---|
六层上下文架构 | context-layer/ | ContextLayer enum, LayeredContext |
层间读取优先级 | LayeredContext.java | resolveKey() - 逐层查找 |
层间写入策略 | LayeredContext.java | write() - 权限校验+自动升级 |
D1压缩触发检测 | CompressTriggerDetector.java | detect() - 阈值+注意力5维 |
规则驱动压缩 | RuleDrivenCompressor.java | compress() - PRESERVE_KEYS+COMPRESS_BLOCKS |
LLM参与压缩 | LlmCompressEngine.java | compressWithLlm() - 工具链调用 |
二次压缩 | SecondaryCompressor.java | compressToProcessSummary() |
D2分裂层策略 | ContextSplitter.java | split() - 各层策略分发 |
LLM分支条件判断 | BranchConditionEvaluator.java | evaluateWithLlm() |
分支评估算法 | BranchQualityEvaluator.java | evaluate() - 3维评分 |
D3冲突检测 | ConflictDetector.java | detectConflicts() - 逐key比较 |
三种合并策略 | MergeStrategyFactory.java | create() - 策略选择 |
LLM冲突解决 | LlmConflictResolver.java | resolve() - Prompt+工具链 |
快照管理 | ContextSnapshotManager.java | saveSnapshot() / loadSnapshot() |
HUMAN回路 | HumanLoopController.java | confirm() / intervene() |
LLM工具链 | tools/ContextInspectTool.java | context_inspect |
LLM工具链 | tools/ContextCompressTool.java | context_compress |
LLM工具链 | tools/ContextBranchTool.java | context_branch |
LLM工具链 | tools/HumanConfirmTool.java | human_confirm |
ActivityExtensionConfig | ActivityExtensionConfig.java | 6维配置POJO |
ContextGovernanceDTO | ContextGovernanceDTO.java | 双端共享模型 |
决策点 | 知识文件 | 内容 |
|---|---|---|
D1压缩决策 | compress-decision.md | 触发条件、压缩规则模板、注意力阈值默认值 |
D2分裂决策 | split-decision.md | 层策略映射表、分支评估算法参数、知识置信度阈值 |
D3合并决策 | merge-decision.md | 冲突检测算法、三种策略适用场景、LLM冲突解决Prompt模板 |
HUMAN回路 | human-loop-rules.md | 4种触发条件定义、16个干预选项说明、超时策略 |
层间交互 | layer-interaction-rules.md | 读取优先级、写入权限矩阵、层间传递规则 |
功能 | 端点 | Method | 对应设计点 |
|---|---|---|---|
查看上下文状态 | /api/context-governance/inspect | POST | context_inspect工具 |
手动压缩 | /api/context-governance/compress | POST | C1干预选项 |
注入上下文 | /api/context-governance/inject | POST | C3干预选项 |
冲突仲裁 | /api/context-governance/resolve | POST | P3干预选项 |
回退快照 | /api/context-governance/rollback | POST | P4干预选项 |
运行时配置 | /api/context-governance/config | POST | C5/L3干预选项 |
获取治理DTO | /api/context-governance/status | GET | ContextGovernanceDTO |
分支评估 | /api/context-governance/branch-evaluate | POST | D2分支评估 |
知识操作 | /api/context-governance/knowledge | POST | K1~K4干预选项 |
将本文的所有设计点与实现对照表交叉验证,确保零遗漏:
设计-实现闭环六层架构(6个层定义+3条交互规则)→ 3个决策点(D1×4步+D2×3步+D3×4步)→ HUMAN回路(4触发×16选项)→ LLM工具链(4工具×N序列)→ 业务定制(6维配置+3Tab面板+4看板)→ 9个REST端点 → 全部有代码实现对应。
这个对照表不仅是文档,更是代码审查和测试覆盖的基准:每个设计点都应该有对应的单元测试,每个REST端点都应该有对应的集成测试。
class LayeredContext {
// 六层存储,每层是一个Map
private Map<ContextLayer, Map<String, Object>> layers;
// 读取:按优先级从L0到L5逐层查找
Object resolveKey(String key) {
for (ContextLayer layer : ContextLayer.values()) {
Map<String, Object> layerData = layers.get(layer);
if (layerData.containsKey(key)) {
return layerData.get(key);
}
}
return null; // key不存在
}
// 写入:指定层级 + 权限校验 + 自动升级
void write(ContextLayer targetLayer, String key, Object value) {
// 1. 权限校验
if (targetLayer == SYSTEM) throw new ContextWriteDeniedException();
if (targetLayer == PROCESS && layers.get(PROCESS).containsKey(key))
throw new ContextWriteDeniedException("PROCESS层仅允许追加");
// 2. 自动升级:如果更底层已有该key,升级到那个层
ContextLayer actualLayer = findExistingLayer(key);
if (actualLayer != null && actualLayer.ordinal() < targetLayer.ordinal())
targetLayer = actualLayer;
// 3. 写入
layers.get(targetLayer).put(key, value);
}
}class CompressTriggerDetector {
boolean detect(LayeredContext context, ActivityExtensionConfig config) {
// 阈值检测
int totalTokens = context.getTokenCount(L3) + context.getTokenCount(L4);
if (totalTokens > config.getCompressTokenThreshold()) return true;
int msgCount = context.getMessageCount(L3);
if (msgCount > config.getCompressMessageThreshold()) return true;
// 注意力5维检测
AttentionScore score = calculateAttentionScore(context);
if (score.getDensity() < 0.15) return true; // 关键信息密度过低
if (score.getRedundancy() > 0.3) return true; // 冗余度过高
if (score.getDecay() < 0.6) return true; // 时序衰减严重
if (score.getConflict() > 0.05) return true; // 语义冲突
if (score.getToolEfficiency() < 0.5) return true; // 工具调用效率低
return false;
}
AttentionScore calculateAttentionScore(LayeredContext context) {
// 1. 密度:preserveKeys对应token / 总token
double density = calculateDensity(context);
// 2. 冗余:相似消息对数 / 总消息对数
double redundancy = calculateRedundancy(context);
// 3. 衰减:最近N轮注意力权重 / 总权重
double decay = calculateTemporalDecay(context);
// 4. 冲突:矛盾key数 / 总key数
double conflict = calculateSemanticConflict(context);
// 5. 工具效率:有效工具返回 / 总工具调用
double toolEff = calculateToolEfficiency(context);
return new AttentionScore(density, redundancy, decay, conflict, toolEff);
}
}class ContextSplitter {
List<LayeredContext> split(LayeredContext source, SplitGateway gateway) {
// 保存快照(合并时的基准)
ContextSnapshot snapshot = snapshotManager.saveSnapshot(source);
List<LayeredContext> branches = new ArrayList<>();
for (BranchDefinition branch : gateway.getBranches()) {
LayeredContext branchContext = new LayeredContext();
// L0/L1: 共享(引用传递)
branchContext.setLayer(SYSTEM, source.getLayer(SYSTEM));
branchContext.setLayer(PROCESS, source.getLayer(PROCESS));
// L2: 继承(深拷贝基线 + 增量独立)
Map<String, Object> knowledgeCopy = deepCopy(source.getLayer(KNOWLEDGE));
branchContext.setLayer(KNOWLEDGE, knowledgeCopy);
// L3: 独立(深拷贝,各自累积)
Map<String, Object> historyCopy = deepCopy(source.getLayer(HISTORY));
branchContext.setLayer(HISTORY, historyCopy);
// L4: 深拷贝 + 分支条件注入
Map<String, Object> workingCopy = deepCopy(source.getLayer(WORKING));
branchContext.setLayer(WORKING, workingCopy);
// 注入分支条件变量
branch.getContextInject().forEach((k, v) ->
branchContext.write(WORKING, k, v));
branchContext.write(WORKING, "_branch_id", branch.getId());
branchContext.write(WORKING, "_snapshot_id", snapshot.getId());
// L5: 清空(不传递)
branchContext.setLayer(EPHEMERAL, new HashMap<>());
branches.add(branchContext);
}
return branches;
}
}class ConflictDetector {
List<MergedConflict> detectConflicts(
Map<String, Object> base,
List<Map<String, Object>> branches) {
List<MergedConflict> conflicts = new ArrayList<>();
// 收集所有key
Set<String> allKeys = new HashSet<>();
branches.forEach(b -> allKeys.addAll(b.keySet()));
for (String key : allKeys) {
Object baseValue = base.get(key);
// 收集各分支的值(排除与base相同的)
Set<Object> uniqueModifiedValues = new HashSet<>();
List<String> modifyingBranches = new ArrayList<>();
for (int i = 0; i < branches.size(); i++) {
Object branchValue = branches.get(i).get(key);
if (branchValue != null && !branchValue.equals(baseValue)) {
uniqueModifiedValues.add(branchValue);
modifyingBranches.add("branch_" + i);
}
}
if (uniqueModifiedValues.size() > 1) {
// 多个分支对同一key写入了不同值 → 冲突
conflicts.add(new MergedConflict(
key, baseValue,
new ArrayList<>(uniqueModifiedValues),
modifyingBranches
));
}
}
return conflicts;
}
}class RuleDrivenCompressor {
CompressResult compress(LayeredContext context, ActivityExtensionConfig config) {
CompressResult result = new CompressResult();
Map<String, Object> history = context.getLayer(HISTORY);
// 1. 提取PRESERVE_KEYS(无条件保留)
Map<String, Object> preserved = new HashMap<>();
for (String key : config.getPreserveKeys()) {
if (history.containsKey(key)) {
preserved.put(key, history.get(key));
}
}
// 2. 应用COMPRESS_BLOCKS规则
Map<String, Object> compressed = new HashMap<>(preserved);
for (CompressRule rule : config.getCompressRules()) {
List<Map.Entry<String, Object>> matched = findMatches(history, rule.getPattern());
for (Map.Entry<String, Object> entry : matched) {
switch (rule.getAction()) {
case "extract_keys":
Map<String, Object> extracted = extractKeys(entry.getValue(), rule.getExtractKeys());
compressed.put(entry.getKey(), extracted);
break;
case "summarize":
String summary = summarize(entry.getValue(), rule.getMaxTokens());
compressed.put(entry.getKey() + "_summary", summary);
break;
case "count_only":
compressed.put(entry.getKey() + "_count", matched.size());
if (rule.getKeepLast() > 0) {
compressed.put(entry.getKey() + "_last",
matched.get(matched.size() - 1).getValue());
}
break;
}
}
}
// 3. 替换HISTORY层
int beforeTokens = context.getTokenCount(HISTORY);
context.setLayer(HISTORY, compressed);
int afterTokens = context.getTokenCount(HISTORY);
result.setBeforeTokens(beforeTokens);
result.setAfterTokens(afterTokens);
result.setCompressionRatio(1.0 - (double)afterTokens / beforeTokens);
return result;
}
}以一个典型的贷款审批流程为例,展示上下文治理的端到端工作流程:
流程: 提交申请 → 风险评估 → [XOR_SPLIT] → 快速通道 / 完整审核 → [AND_JOIN] → 放款决策
═══ 活动1: 提交申请 ═══
L4 WORKING: {amount: 50000, applicant_id: "APP001", purpose: "经营贷"}
L3 HISTORY: [] (流程刚开始)
→ 活动完成,WORKING→HISTORY迁移
L3 HISTORY: [{activity: "submit", summary: "申请50万经营贷", keys: {amount, applicant_id}}]
═══ 活动2: 风险评估 ═══
L4 WORKING: {amount: 50000, applicant_id: "APP001"} (从HISTORY恢复的关键key)
L2 KNOWLEDGE: {风险评估规则, 行业黑名单} (RAG检索)
→ LLM调用: 结合WORKING和KNOWLEDGE进行风险评估
L4 WORKING: {risk_level: "medium", risk_factors: ["新客户", "跨行业"], assessment_id: "RA001"}
→ 活动完成,WORKING→HISTORY迁移
L3 HISTORY: [{submit...}, {activity: "risk_assess", summary: "风险中等", keys: {risk_level, assessment_id}}]
═══ D2: XOR_SPLIT 分裂决策 ═══
条件: risk_level == "low" AND amount < 50000 → 快速通道
当前: risk_level = "medium" → 走完整审核
→ 分裂时:
- 保存快照 snap_001
- WORKING深拷贝 + 注入 {track_type: "full", requires_approval: true}
═══ 活动3: 完整审核(包含并行分支) ═══
[XOR_SPLIT] → 财务审核 + 风险复核 (PARALLEL_SPLIT)
→ 分支A(财务): WORKING = 拷贝 + {review_type: "finance"}
→ 分支B(风险): WORKING = 拷贝 + {review_type: "risk"}
═══ D3: AND_JOIN 合并决策 ═══
分支A结果: {approval_status: "approved", finance_comment: "收入稳定"}
分支B结果: {approval_status: "rejected", risk_comment: "异常交易模式"}
→ 冲突检测: approval_status冲突 (approved vs rejected)
→ 策略: MERGE_WITH_CONFLICT_DETECT
→ LLM冲突解决: 结合risk_level=medium, 公司政策 → 升级为双人审批
→ human_confirm: 用户确认 → 最终值: "pending_dual_approval"
═══ 活动4: 放款决策 ═══
L3 HISTORY: [所有前置活动的摘要, 包括冲突解决记录]
L4 WORKING: {approval_status: "pending_dual_approval", ...}
→ 压缩检测: HISTORY层token > 阈值 → 触发压缩
→ 压缩后: HISTORY保留关键决策链,token从5000降至1800端到端验证在上述场景中,六层架构确保了各活动间的上下文隔离与传递,D2分裂决策确保了分支条件的正确注入,D3合并决策确保了冲突的检测与解决,D1压缩决策确保了长流程中上下文不失控,HUMAN回路确保了关键决策有人类把关。这正是上下文治理的价值所在。
上下文治理不是孤立的设计,它与流程驱动架构的其他核心设计紧密关联:
关联设计 | 交互点 | 说明 |
|---|---|---|
流程定义与实例二元结构 | L1 PROCESS层 | 流程定义构成PROCESS层的基础内容,流程变量存储在PROCESS层 |
语义感知的分裂合并 | D2/D3决策点 | 分裂合并的语义感知依赖上下文治理的层策略和冲突检测 |
可信回退与历史恢复 | 快照机制 | 上下文快照是可信回退的基础,恢复操作即加载指定快照 |
知识飞轮闭环 | L2 KNOWLEDGE层 | 知识飞轮的产物写入KNOWLEDGE层,KNOWLEDGE层的内容参与知识飞轮 |
LLM增强压缩引擎 | D1压缩决策 | 压缩引擎是D1决策的核心实现,本文细化了其触发条件和执行策略 |
多引擎协作 | LLM工具链 | 上下文治理工具(context_inspect/compress/branch)是多引擎协作的工具集之一 |
上下文治理是一个持续演进的设计,随业务复杂度增长而逐步增强:
阶段 | 能力 | 典型场景 | 关键实现 |
|---|---|---|---|
MVP | 基础分层 + 规则压缩 | 单链路流程,5个以内活动 | LayeredContext + RuleDrivenCompressor |
V1 | + LLM参与压缩 + 分裂合并 | 含分支流程,10~20个活动 | LlmCompressEngine + ContextSplitter + ConflictDetector |
V2 | + HUMAN回路 + 知识飞轮 | 高风险场景,需人工把关 | HumanLoopController + 知识置信度管理 |
V3 | + 业务定制面板 + 运行时看板 | 多业务线,各线策略不同 | ActivityExtensionConfig + ContextGovernanceDTO |
V4 | + 自适应治理 + 跨流程知识 | 超大规模,跨流程知识共享 | 自适应阈值调整 + 跨流程KNOWLEDGE联邦 |
在上下文治理的实践中,存在若干常见反模式,需要刻意规避:
反模式1:全量上下文传递将所有历史消息全量传递给LLM,不做任何压缩或过滤。这导致token线性膨胀、注意力稀释、成本失控。正确做法:始终使用六层架构,每层独立治理,WORKING层仅保留当前活动必要信息。
反模式2:过度压缩为了节省token,将HISTORY层压缩到只剩最终结果,丢失了决策推理过程。后续活动需要理解"为什么做出那个决策"时,信息不可得。正确做法:PRESERVE_KEYS必须包含决策因果链的关键节点,压缩摘要必须保留"做了什么决策"+"为什么"。
反模式3:分支间L0/L1层深拷贝分裂时将SYSTEM和PROCESS层也深拷贝,导致各分支看到的系统规则和流程定义不一致。如果运行时修改了某个分支的SYSTEM层(如修改了安全约束),其他分支不受影响,产生行为不一致。正确做法:L0/L1层始终共享引用,确保全局一致性。
反模式4:LAST_WRITE_WINS滥用在分支间存在语义关联的场景下使用LAST_WRITE_WINS合并策略,导致重要分支的决策被覆盖。例如风险分支的"拒绝"被后完成的财务分支的"通过"覆盖,但风险问题并未解决。正确做法:分支间有语义关联时,必须使用MERGE_WITH_CONFLICT_DETECT。
陷阱:HUMAN回路超时无策略如果HUMAN确认超时后没有预设的降级策略,流程将永久阻塞。必须在humanLoopConfig中配置超时策略:自动选择最保守值 / 自动重试 / 自动升级到上级审批人。
陷阱:知识注入不设置信度门控RAG检索结果直接注入KNOWLEDGE层,不检查置信度。低质量知识(检索偏差、文档过时)会污染上下文,导致LLM基于错误知识做出错误决策。必须在knowledgeConfig中设置confidenceThreshold。
上下文治理的效果需要量化度量,才能持续优化。核心度量指标:
指标 | 计算方法 | 目标 | 告警阈值 |
|---|---|---|---|
上下文利用率 | 有效token / 总token | > 0.6 | < 0.4 |
压缩保留率 | 压缩后token / 压缩前token | 0.3~0.5 | < 0.2 (过度压缩) |
关键信息保留率 | 压缩后preserveKeys数 / 压缩前preserveKeys数 | 1.0 | < 1.0 |
冲突解决耗时 | 从检测到冲突到解决的时间 | < 30s | > 120s |
HUMAN回路响应率 | HUMAN确认响应数 / 触发数 | > 0.95 | < 0.8 |
分裂后分支质量 | BranchQuality平均值 | > 0.8 | < 0.5 |
注意力健康度 | 5维评分加权平均 | > 0.7 | < 0.4 |
层大小均衡度 | 1 - (max_layer_ratio - min_layer_ratio) | > 0.6 | < 0.3 |
GovernanceHealth = w1×UtilizationRate + w2×RetentionRate + w3×KeyPreservation + w4×AttentionHealth + w5×BranchQuality
其中w1~w5为业务权重,不同业务场景可调整。当GovernanceHealth持续低于阈值时,触发治理策略自动调整:降低压缩阈值、增加PRESERVE_KEYS、切换到LLM_ASSISTED压缩等。
A: 六层架构支持退化模式。简单场景下,可以退化到3层(SYSTEM+HISTORY+WORKING),KNOWLEDGE/PROCESS/EPHEMERAL层设为空。系统提供ContextProfile.SIMPLE / ContextProfile.STANDARD / ContextProfile.FULL三档配置,根据流程复杂度自动选择。
A: 存在这个风险。LLM压缩可能"创造"原始上下文中不存在的信息。防范措施:(1) 压缩后验证preserveKeys全部保留且值未变;(2) 压缩摘要仅允许"删减"不允许"创造"——prompt中明确要求只做信息提取和概括;(3) 可选的human_confirm验证压缩结果。
A: 采用Copy-on-Write策略。初始分裂时L2层仅做浅拷贝(共享内部数据结构),只有在分支实际写入L2层时才触发深拷贝。大多数分支只读L2层知识而不写入,因此Copy-on-Write可以节省60%+的内存开销。
A: LLM解决冲突不是100%可靠的,因此设计了三级保障:(1) LLM解决结果必须通过一致性校验(与PROCESS层约束不矛盾);(2) 对于高影响冲突(如审批状态、金额),自动升级为HUMAN确认;(3) 所有LLM解决结果记录审计日志,支持事后追溯和修正。
A: 上下文治理是应用层设计,ChatML/Tool Use是传输层协议。六层架构决定"哪些信息应该给LLM",ChatML决定"这些信息如何格式化传输给LLM"。治理层做出决策后,将选中的上下文按ChatML格式组装为messages数组,通过Tool Use协议传递给LLM。
A: 流程中断恢复时,从持久化存储重建六层上下文:L0/L1从流程定义重建,L2从知识库+增量日志重建,L3/L4从活动实例存储重建,L5清空。如果分裂快照存在且流程处于分支执行中,还需恢复分支上下文和快照引用。整个过程对LLM透明——恢复后的上下文与中断前完全一致。
以下是本设计中的关键架构决策记录:
ADR | 决策 | 替代方案 | 选择原因 |
|---|---|---|---|
ADR-001 | 采用6层而非4层架构 | 4层(SYSTEM/HISTORY/WORKING/EPHEMERAL) | PROCESS和KNOWLEDGE的独立使得流程级配置和知识管理可独立演化,避免与HISTORY耦合 |
ADR-002 | L0/L1共享而非深拷贝 | 全层深拷贝 | 共享保证全局一致性,避免分支间系统规则/流程定义不一致 |
ADR-003 | 冲突检测采用基准快照 | 分支间互相比较 | 基准比较O(N),分支间比较O(N²),且基准可区分新增/修改 |
ADR-004 | 规则优先于LLM | LLM优先 | 规则确定性高、延迟低、成本零;LLM仅处理规则无法覆盖的模糊场景 |
ADR-005 | 工具调用而非直接操作 | LLM直接操作内存 | 工具调用可审计、可回滚、可限流、可权限控制 |
ADR-006 | 5维注意力检测 | 单一token阈值 | 单一阈值无法捕获注意力稀释、冗余、冲突等质量问题 |
ADR-007 | Copy-on-Write分裂 | 全量深拷贝 | 大多数分支只读L2,COW节省60%+内存,写入时才拷贝 |
ADR-008 | ContextGovernanceDTO双端模型 | 各自独立模型 | 共享契约确保Designer和Chat的"所见即所治",避免状态不一致 |
总结Agent上下文治理是流程驱动架构的基石。六层上下文架构提供了分层治理的结构基础,三大决策点(D1压缩/D2分裂/D3合并)定义了上下文在生命周期关键节点的行为,HUMAN回路确保关键决策有人类把关,LLM工具链将治理操作封装为可审计的工具调用,ActivityExtensionConfig实现业务定制。五者协同,构成可治理、可观测、可干预的上下文体系 —— 这是流程驱动Agent从"能用"走向"可靠"的关键一步。
公式 | 含义 |
|---|---|
TokenTotal = |SYSTEM| + |PROCESS| + Σ(Activity_history + Activity_knowledge) + |WORKING| + |TOOLS| | 上下文总Token量 |
CompressTrigger = TokenExceed ∨ MsgExceed ∨ ActivityExceed ∨ AttentionDegrade | 压缩触发条件 |
BranchQuality = α×KeyCoverage + β×ValueConsistency + γ×KnowledgeConfidence | 分支上下文质量 |
GovernanceHealth = w1×Util + w2×Retain + w3×KeyPres + w4×Attn + w5×BranchQ | 治理健康度 |
文件 | 职责 |
|---|---|
LayeredContext.java | 六层上下文核心数据结构与读写 |
Agent上下文治理:流程驱动架构中的深度设计sTriggerDetector.java | 压缩触发检测(阈值+注意力5维) |
RuleDrivenCompressor.java | 规则驱动压缩引擎 |
LlmCompressEngine.java | LLM参与压缩引擎 |
ContextSplitter.java | 分裂层策略实现 |
ConflictDetector.java | 合并冲突检测 |
ActivityExtensionConfig.java | 6维业务定制配置 |
ContextGovernanceDTO.java | Designer/Chat双端共享模型 |
Agent上下文治理:流程驱动架构中的深度设计 · 架构设计 · 2026
六层架构 · 三大决策点 · HUMAN回路 · LLM工具链 · 业务定制规则
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。