Agent 治理工具包 ACS 遥测日志规范指南:事件词汇、脱敏边界与 OTel 指标桥接
【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址: https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkit
本篇技术指南围绕 agent-governance-toolkit 政策引擎(policy-engine)中的 ACS 日志风格指南 展开,系统讲解 ACS(Agent Control Specification)遥测与日志发射的规范性约定——包括规范事件词汇表、字段命名规则、脱敏边界、严重级别映射以及贡献者提交规则。读完本文,你将掌握如何在 ACS 生态中正确发射脱敏安全的遥测事件、如何把决策事件映射为 OpenTelemetry 计数器与直方图,以及如何通过仓库自带的 lint 脚本(lint_logging.py)在提交前自动校验事件词汇与脱敏合规。
指南定位:只观测、不干预的遥测契约
logging-style-guide.md是 ACS 遥测与日志发射的**规范性(normative)**文档。其核心定位有三条:
- 镜像两层事实来源:事件模型以 policy-engine/docs/observability.md 为语义第一来源,Rust 侧
TelemetryEventType枚举(位于引擎 crateagent-control-spec的telemetry.rs)是事件名称的运行时来源。 - Evaluate only:ACS 遥测只记录策略评估事实(evaluation facts),绝不改变强制(enforcement)行为,也不暴露受保护内容。
- 可测试、可评审:指南中的规范 JSON 块被
<!-- acs telemetry vocabulary start -->与<!-- acs telemetry vocabulary end -->标记包裹,既是评审目标,也是 lint 与 parity 测试的比对基准。
从仓库结构看,引擎本身已迁移到 vendored 的agent-control-speccrate(policy-engine/scripts/lint_logging.py 的注释明确说明telemetry.rs、runtime.rs已不在本仓库),而 AGT 保留的遥测 sink 层位于 policy-engine/core/src/telemetry_sinks.rs。该文件实现了TelemetrySinktrait 的三个增强型 sink:InMemoryTelemetrySink(按序记录所有事件,供测试与本地检查)、StdoutJsonTelemetrySink(每行一个脱敏安全 JSON,覆盖 audit.jsonl 场景)、MultiSink(把同一事件扇出到多个 sink,并用catch_unwind隔离单个 sink 的 panic,确保遥测永远不会成为强制的加载路径)。
规范事件词汇表:七个事件类型的完整契约
指南的规范块定义了 ACS 遥测的全部事件词汇(schema_version = 1)。每个事件都区分required_fields(必填)、optional_fields(可选)与documented_attribute_keys(文档化的完整属性键集合),后者必须与 policy-engine/tests/parity/telemetry_redaction_canonical.json 中该事件的emitted_attribute_keys完全一致。
decision(决策事件)
每次干预点(intervention point)评估都会发射一次,是遥测的主力事件:
- 必填字段:
event_type、intervention_point、decision、enforcement_mode、duration_ms - 可选字段:
reason_code、error_class、policy_id、annotators、action_identity - 文档化属性键:上述全部 10 个字段
annotator_dispatch(标注器调度事件)
- 必填字段:
event_type、intervention_point、annotators、duration_ms - 可选字段:
reason_code、error_class
policy_evaluation(策略评估事件)
- 必填字段:
event_type、intervention_point、policy_id、duration_ms、metadata.policy_type - 可选字段:
reason_code、error_class - 注意:这是唯一把扩展元数据
metadata.policy_type列为必填的事件。
evaluation_timing(评估耗时事件)
- 必填字段:
event_type、intervention_point、decision、enforcement_mode、duration_ms - 可选字段:
reason_code、error_class、policy_id、action_identity
intervention_point.transformed(干预点变换事件)
该事件由 AGT D2 增加,在判定结果为transform时,除基础decision事件外额外发射一次,依据 [policy-engine/docs/spec/SPECIFICATION.md] 第 14 节(docs/spec/目录):
- 必填字段:
event_type、intervention_point、policy_id、enforcement_mode、decision、duration_ms - 可选字段:
reason_code、annotators、evidence_artefact、evidence_verification_pointer_keys - 其中
evidence_artefact与evidence_verification_pointer_keys携带证据校验信息:前者是逐字的artefact字符串,后者是排序后的指针键列表(绝不包含 URL 值),以此控制遥测基数——审计者按需从审计记录中恢复完整 URL 映射。此规则在 policy-engine/integrations/otel/src/lib.rs 的测试中被防御性验证:任何属性值中不得出现https://。
annotator_failed(标注器失败事件)
- 必填字段:
event_type、intervention_point、annotators、reason_code、error_class - 可选字段:空
policy_failed(策略失败事件)
- 必填字段:
event_type、intervention_point、policy_id、reason_code、error_class、metadata.policy_type - 可选字段:空
对照 policy-engine/docs/observability.md 可知:上游effect_applied事件已依据 SPECIFICATION 第 19 节移除(effects 不再属于判定表面);intervention_point.transformed则是在基础 decision 之外补充发射的。observability.md同时强调"Decision events are emitted once for every intervention point evaluation"——每个干预点评估恰好发射一次决策事件。
命名规则:稳定、小写、snake_case
指南的命名规则清晰且可机器校验:
- 事件类型线上值(wire values)使用小写 snake_case,且必须保持稳定。例如
policy_evaluation、intervention_point.transformed,一旦发布不得随意变更。 - 字段名使用小写 snake_case(含
action_identity、enforcement_mode、duration_ms等)。 - 元数据键遵循同一规则,并在文档中以
metadata.前缀标注(如metadata.policy_type),用于区分扩展元数据与基础字段。 - 新增名称必须一次性同步四处:
docs/observability.md、本指南、lint 覆盖、canonical parity 测试——同一变更中完成,防止三处漂移。
lint 脚本在 policy-engine/scripts/lint_logging.py 中实现了这套规则的自动校验:valid_field_name要求字段按.分段后每段只能由小写字母、数字与下划线组成;check_vocabulary会强制"指南事件名 ==TelemetryEventType枚举值 == observability.md 中的 known event kinds == 脱敏 fixture 事件名"四者完全相等(L174-L176),并校验每个文档化字段要么属于BASE_FIELDS(10 个基础字段),要么以metadata.开头(L178-L192)。
脱敏规则:遥测永远不携带原始负载
脱敏是 ACS 遥测的"承重墙"(load-bearing invariant),指南给出了明确的禁区清单与安全类别清单:
遥测中严禁出现的内容:原始策略目标值(raw policy target values)、快照输入、快照输出、模型请求、模型响应、消息、工具参数、工具结果、标注负载值、脱敏替换文本、密钥(secrets)、PII。
允许的安全字段类别:稳定标识符、动作身份哈希(action identity hashes)、名称、模式、决策、原因码、错误类别、耗时、计数、长度、span 计数。
自由文本策略原因的处理:除非已塑形为低基数标识符,否则一律以policy_reason上报。Python SDK 中的 policy-engine/sdk/python/agent_control_specification/_telemetry.py 给出了可运行的实现:_is_identifier_reason_code要求原因非空、不超过 96 字节且仅由 ASCII 字母数字加_-.:/组成(L70-L83);safe_reason_code对不满足条件的自由文本一律折叠为常量policy_reason(L86-L99)。
action_identity 的双重特性:它是规范策略输入的sha256:摘要,可安全用于关联(不泄露底层策略目标、快照、标注值或投影工具数据),但由于其高基数特性,OpenTelemetry 指标桥接层不会把它挂到计数器或直方图上(见 policy-engine/docs/observability.md 与 policy-engine/integrations/otel/src/lib.rs 的mapping_omits_action_identity测试)。
这一契约在 policy-engine/tests/parity/telemetry_redaction_canonical.json 中被固化为可执行证据:每个事件都声明了guaranteed_withheld_fields(保证扣留字段,如policy_target.value、snapshot.input、snapshot.model_request、snapshot.tool_call.args、annotations.*、secrets、pii等)与safe_attribute_classes。lint_logging.py中的SENSITIVE_TOKENS集合(L34-L54)会在扫描 Rust 发射点时拦截任何疑似携带负载的元数据键——即使引擎源码未 vendored 本地,仓库自有部分(OTel 桥接、Rust sink、各 SDK)仍会被全面检查。
严重级别规则:核心事件无 severity,宿主不得重解释
指南明确规定:
- 核心遥测事件不携带 severity 字段。
- OTel 集成把事件映射为计数器与直方图,而不是日志级别。
- 宿主 sink 可以把 denied 或 failed 结果映射到自己的日志级别,但不得添加负载字段,也不得把遥测重新解释为强制决策(即不能把日志映射当策略判定来用)。
OTel 桥接层的实现印证了这一点:policy-engine/integrations/otel/src/lib.rs 中的OtelTelemetrySink在构造时一次性构建所有 instrument:为allow、deny、transform三种线上决策值各建一个f64_counter(acs_intervention_{decision}_total),外加acs_intervention_duration_ms的f64_histogram(L26-L32)。emit只做三件事:属性映射、缓存计数器查找、直方图记录(L56-L76)。
值得注意的细节是records_metrics(L83-L85):只有基础decision事件才记录指标。由于 transform 判定会同时发射decision与intervention_point.transformed两个事件,且 perf 遥测下的evaluation_timing也携带 decision,若全部计指标会导致一次评估被重复计数。因此 OTel 桥接刻意只在基础 Decision 事件上递增计数器与记录耗时,保证"每次评估恰好一次递增、一次耗时采样"(测试only_the_base_decision_event_records_metrics对全部 7 种事件类型逐一断言)。
性能遥测旋钮:PerfTelemetry 的三级开关
来自 policy-engine/docs/observability.md 的补充:PerfTelemetry是运行时级别,线上值为 0、1、2,默认 0。
| Wire | Level | Annotator dispatch 与 policy evaluation 成本 | Evaluation timing |
|---|---|---|---|
| 0 | Off | No | No |
| 1 | External | Yes | No |
| 2 | Full | Yes | Yes |
External 事件携带干预点归属以及标注器名或策略 ID;失败的外部调用还会携带运行时原因。Full 则在始终发射的 decision 事件之外,增加每次评估的 timing。
多语言 SDK 的一致性镜像
指南规范并不止于 Rust 核心:各语言 SDK 以_telemetry.py这类模块镜像同一套字段集与指标名,保证异构宿主发射出相同的事件形状。例如 policy-engine/sdk/python/agent_control_specification/_telemetry.py:
TelemetryEventType枚举完整镜像 Rust 的 7 个线上字符串(L53-L67);TelemetryEvent.from_result从评估结果构造脱敏安全事件,reason_code经safe_reason_code折叠、error_class经error_class_for从runtime_error:/host_error:前缀推导(L102-L118);OtelMetricsTelemetrySink惰性导入opentelemetry,缺失时降级为安全 no-op 并仅告警一次(L405-L436),且同样只对基础 decision 事件计指标、以 float 计数以匹配 Rust 的f64_counter(L446-L464);MultiSink逐个扇出并吞掉单个 sink 的异常(L306-L351),与 Rust 侧catch_unwind隔离策略一一对应。
仓库还提供对应的一致性测试与 harness:Node 侧 policy-engine/sdk/node/src/telemetry.ts 与 policy-engine/sdk/node/test/telemetry.test.mjs、Python 侧 policy-engine/sdk/python/tests/test_telemetry.py、.NET 侧 policy-engine/sdk/dotnet/src/AgentControlSpecification/Telemetry.cs 与TelemetryHarness.cs,以及 Rust 的 policy-engine/sdk/rust/tests/upstream_compatibility.rs,均可作为多语言实现的对照阅读入口。
贡献者规则与提交前检查清单
指南对提交遥测相关变更的贡献者给出四条硬性约束:
- 不得添加临时事件类型字符串:一律使用
TelemetryEventType与TelemetryEvent(在引擎 crate 中定义),任何新事件都必须进入规范词汇表并通过 parity 校验。 - 不得添加未文档化的元数据键:除非本指南与
docs/observability.md同时记录,否则metadata.*键不允许出现。lint_logging.py的scan_rust_emissions会逐文件扫描with_metadata("...")调用并比对 allowed 集合(L204-L209)。 - 保持遥测 sink 故障与强制隔离:sink 失败(含 panic)绝不允许改变强制结果——这正是
TelemetrySink的 fail-safe 设计与MultiSink的catch_unwind隔离语义。 - 示例与测试与生产遥测分离:示例代码与测试不得混入生产遥测发射路径。
提交前运行 lint 是强制动作(对应指南原文的命令,仓库根目录为policy-engine/):
python3 scripts/lint_logging.py该脚本实际完成的校验(policy-engine/scripts/lint_logging.py)包括:提取指南中<!-- acs telemetry vocabulary ... -->标记间的 JSON 块并做风格校验(禁 em dash、禁散文冒号)、比对四源事件名一致性、校验字段 snake_case 与 allowed 集合、扫描所有 Rust 文件中的TelemetryEventType::*用法与metadata键、扫描 OTel 桥接层禁止的高基数属性(action_identity被显式列入OTEL_DISALLOWED_FIELDS)以及任何未文档化属性。全部通过时输出lint_logging.py: clean,否则逐条输出logging lint violation:并返回非零退出码。
小结
ACS 日志风格指南本质上是把"遥测安全"从口头约定固化为可机器校验的契约:规范词汇表定义事件形状,命名规则保证线上稳定性,脱敏规则划定数据边界,severity 规则约束宿主行为,而lint_logging.py与 canonical parity fixture 把这一切变成提交前自动化的质量闸门。对任何在 agent-governance-toolkit 政策引擎上做二次开发、接入新策略注解器或构建自定义遥测 sink 的开发者而言,遵循这份指南即可保证遥测既可用于审计与可观测性,又不会成为策略目标或提示词等敏感内容的新泄露通道。
【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址: https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考