AI Agent 的一次任务,往往会穿过用户输入、记忆检索、模型推理、工具调用和外部服务。如果审计系统只盯着某个请求里是否出现手机号、密钥或身份证号,很容易把正常的内部处理和真正的数据外传混在一起。AgentLoop 所强调的方向,是把单点命中放回语义链路:风险究竟越过了什么边界、影响了谁、证据位于哪一步,以及处置动作应该落在哪里。
单点规则为什么不够
假设审计规则在一段文本里发现了邮箱地址,至少存在三种完全不同的情况:
- Agent 从内部客户系统读取邮箱,但只在受控模型中做分类。
- Agent 将邮箱脱敏后写入内部工单。
- Agent 把原始邮箱作为参数发送给未经批准的第三方工具。
三者都可能触发“检测到邮箱”规则,但只有结合数据来源、处理方式、调用目标和信任边界,才能判断风险等级。审计需要回答的不是“哪里出现了敏感字符串”,而是下面这条链路是否成立:
敏感对象 -> 被哪个 Agent 读取 -> 经过什么转换 -> 发往哪个工具 -> 是否跨越信任边界
因此,语义链路还原至少需要保留五类信息:
| 信息 | 示例 | 审计用途 |
|---|---|---|
| 数据对象 | customer.email |
识别受影响对象 |
| 数据来源 | CRM 检索结果 | 判断数据归属与授权范围 |
| 处理节点 | 模型、脱敏器、插件 | 判断数据是否经过必要转换 |
| 调用目标 | 内部 API、第三方 SaaS | 判断是否越过边界 |
| 关联标识 | trace_id、span_id |
还原完整调用顺序 |
关键点在于:命中规则只是证据,不应直接等同于事故。系统还要证明敏感数据从受控区域流向了不符合策略的目标。
把告警组织成可解释的风险事件
一条能够进入高危队列的事件,应该同时给出四个维度。
边界:例如从 internal 信任域进入 external-unapproved 信任域,而不是笼统地写“发生外部调用”。
对象:说明涉及邮箱、访问令牌还是客户记录,并尽可能给出数量、所属业务与数据主体。证据中应使用掩码或摘要,避免审计平台再次存储明文敏感数据。
链路:记录读取、转换、模型调用和工具调用之间的因果关系。仅靠时间接近不能可靠证明数据流向,事件之间还需要共享追踪标识和字段级数据标签。
处置:明确下一步是阻断工具调用、轮换凭据、通知数据负责人,还是转入人工复核。审计结果如果只给风险分数,值班人员仍然要重新调查整条链路。
“精准”也不等于把不确定事件丢掉。更稳妥的做法是设置多个队列:证据完整且跨越高风险边界的事件进入高危队列;链路不完整但存在敏感数据命中的事件进入待复核队列;确认处于授权范围内的事件则保留审计记录,不触发紧急响应。
可以这样实践:构造最小语义链路审计器
来源摘要没有给出 AgentLoop 的具体 SDK 或事件协议。下面是一个可以直接运行的最小示例,用来演示如何把离散事件组合成风险事件,而不是模拟某个未公开接口。运行环境只需要 Python 3.10 及以上版本。
将以下内容保存为 semantic_audit.py,然后执行 python semantic_audit.py:
from dataclasses import dataclass
from typing import Optional
@dataclass(frozen=True)
class Event:
trace_id: str
step: int
action: str
trust_zone: str
target: str
data_type: Optional[str] = None
data_fingerprint: Optional[str] = None
transformed: bool = False
def reconstruct_incident(events: list[Event]) -> dict:
chain = sorted(events, key=lambda event: event.step)
sensitive = [event for event in chain if event.data_type]
external = [
event for event in chain
if event.action == "tool_call" and event.trust_zone == "external-unapproved"
]
leaked = []
for outbound in external:
for source in sensitive:
same_object = (
source.data_fingerprint
and source.data_fingerprint == outbound.data_fingerprint
)
if source.step < outbound.step and same_object and not outbound.transformed:
leaked.append({
"data_type": source.data_type,
"source": source.target,
"destination": outbound.target,
"evidence_steps": [source.step, outbound.step],
})
if leaked:
severity = "high"
action = "block destination, preserve trace, notify data owner"
elif sensitive and external:
severity = "review"
action = "request field-level lineage or perform manual review"
else:
severity = "informational"
action = "retain audit record"
return {
"trace_id": chain[0].trace_id if chain else None,
"severity": severity,
"boundary": "internal -> external-unapproved" if external else None,
"affected_objects": leaked,
"evidence": [
{
"step": event.step,
"action": event.action,
"target": event.target,
"trust_zone": event.trust_zone,
}
for event in chain
],
"recommended_action": action,
}
events = [
Event("trace-42", 1, "retrieve", "internal", "crm.customer", "email", "sha256:abc"),
Event("trace-42", 2, "model_call", "internal", "approved-model"),
Event(
"trace-42",
3,
"tool_call",
"external-unapproved",
"marketing-plugin.example",
"email",
"sha256:abc",
transformed=False,
),
]
print(reconstruct_incident(events))
这个示例没有在日志中保存邮箱原文,而是用稳定指纹关联同一数据对象。输出会指出跨越的边界、受影响对象、证据步骤和建议动作。生产环境中,指纹应使用带密钥的 HMAC,而不是直接对低熵数据做普通哈希,否则攻击者可能通过字典枚举还原手机号或邮箱。
真正接入 Agent 工作流时,可以在模型网关和工具网关统一生成事件。一个最小事件可以采用下面的结构:
{
"trace_id": "trace-42",
"span_id": "span-3",
"parent_span_id": "span-2",
"action": "tool_call",
"actor": "support-agent",
"target": "marketing-plugin.example",
"trust_zone": "external-unapproved",
"data_labels": ["pii.email"],
"data_fingerprints": ["hmac-sha256:abc"],
"transforms": [],
"policy_version": "2025-01"
}
parent_span_id 用来证明调用关系,data_labels 描述数据类型,data_fingerprints 关联对象,transforms 则记录脱敏、聚合或截断操作。策略版本也必须进入证据,否则策略更新后很难解释历史告警为何成立。
落地时要守住的边界
语义审计并不是记录得越多越好。完整保存提示词、模型响应和工具参数,可能让审计系统本身成为新的敏感数据仓库。落地时应优先记录标签、指纹、调用关系和必要的掩码片段,并为原始内容设置更严格的访问控制与短保留期。
可以用下面的检查表评估是否具备上线条件:
- 所有模型调用和工具调用是否共享稳定的
trace_id。 - 数据标签能否从读取节点传播到转换节点和外发节点。
- 每个目标是否绑定明确的信任域、数据许可范围和负责人。
- 高危事件是否能指出具体边界、对象、证据步骤和处置动作。
- 链路缺失时是否进入复核队列,而不是自动判定无风险。
- 审计证据是否经过掩码、加密,并设置最小访问权限和保留期。
- 阻断策略是否经过影子模式验证,避免直接中断合法业务流程。
Agent 审计的目标不是制造更多告警,而是把一次敏感数据命中还原为可核验的因果链。只有当边界、对象、证据和动作能够同时说明白,高危队列才真正具备响应价值。