ADR
学习专看文学书,也是不好的。先前的文学青年,往往厌恶数学、理化、史地、生物学,以为这些都无足轻重,后来变成连常识也没有。——鲁迅
当 AI Agent 走进企业环境,安全问题就不再只是“提示词防护”那么简单
过去一段时间,大家谈 AI Agent,常常会先聊能力:它能不能写代码,能不能调工具,能不能把任务一步步跑通。
可一旦 Agent 真正进入企业环境,问题的重心就会悄悄变化。
这时候,大家开始关心的已经不是“它会不会做”,而是“它到底做了什么”“它为什么这么做”“它有没有被带偏”“它会不会在看起来正常的流程里做出不安全的动作”。当 Agent 能调用工具、接触代码、访问工作流、读取上下文,它就不再只是一个会回答问题的模型外壳,而更像是一个会行动、会决策、会被诱导、也可能会越界的执行者。
uber/ADR 这套项目,正是冲着这个问题来的。
ADR,全称 Agentic AI Detection and Response。从仓库 description 到 README,它给自己的定位都非常明确:这是一套面向企业 AI Agent 的安全系统,核心围绕 observability、security benchmarking、threat detection 展开,并且已经 部署在 Uber 的生产环境中。
项目地址:https://github.com/uber/ADR
ADR 想解决的,是企业里 AI Agent 的“可见性”和“可控性”
README 一开头就把场景钉得很牢:ADR 服务的是 enterprise security system for AI agents。它面向的对象包括员工使用的 Agent 工具,比如 Cursor、Claude Code、Codex,以及企业内部构建的自定义 AI agents。
这类系统的难点非常现实。因为 Agent 一旦进入工作流,就不仅会“说”,还会“做”:
- 它会调用工具
- 它会读取和生成内容
- 它会沿着上下文做推理
- 它会在看起来合理的任务中,触碰潜在的风险路径
于是,企业需要的不只是一个拦截器,也不只是一个日志系统,而是一整套围绕 Agent 行为的安全能力。
ADR 在 README 中把这套能力分成了四个互补的部分:
- ADR Observability:理解 AI agents 在做什么、为什么这么做
- ADR Benchmark:在真实企业条件下测试 agent security
- ADR Detection:高效检测 risky agent behavior
- ADR Prevention:在危险动作造成损害之前阻止它们
不过 README 也明确说明,ADR Prevention 目前不在当前开源版本中。当前仓库开放的是 Sensor、Benchmark 和 Detector 这几个部分。
这个边界划得很清楚,也让人一眼就明白:这不是一份泛泛而谈的“AI 安全方案”,而是一套已经拆分出清晰组成部分的系统工程。
它不是只盯着“攻击”,而是在试图看清 Agent 的整个行动过程
很多安全讨论,容易把视线直接锁死在“恶意输入”或者“提示词攻击”上。但 ADR 的出发点明显更完整一些。
它先做的第一件事,是 观察。
README 对 ADR Observability 的描述很直接:在生产环境中,它会捕获 agent intent、tool use 和 execution traces,并覆盖 7+ AI coding tools,运行平台包括 macOS、Linux 和 Windows。
这种思路很有意思。它并不是先假设“哪里有问题”,而是先把 Agent 的行为链条尽量还原出来。只有看见,才谈得上分析;只有能解释“为什么这么做”,才有机会判断“这样做是否有风险”。
从这个角度看,ADR 更像是在给企业里的 AI Agent 装上一套安保摄像头、行为记录仪和事后分析台。它不是对着某个单点问题补洞,而是在为 Agent 的行动建立可观测性。
仓库结构不复杂,但分工很鲜明
README 里给出的仓库布局,已经足够让人迅速理解 ADR 的开源部分:
Sensor/:ADR ObservabilityDetection/:ADR Benchmark + Detectiondocs/REPRODUCIBILITY.md:复现实验流程
同时,README 还补了一句很关键的话:仓库包含开源的 ADR Sensor、ADR-Bench 和 ADR Detector;而用于增强 ADR Detection 的离线 ADR Explorer 引擎,不在当前开源范围内。
这意味着开源版的 ADR,已经把“观测”“评测”“检测”三件事铺开了,但仍保留了一部分未开放的离线能力。
Sensor:先把 Agent 的行为翻译成统一可理解的安全遥测
如果说 ADR 是一套企业 Agent 安全系统,那么 Sensor 就像它伸出去的触角。
Sensor/README.md 对它的定位写得很明确:这是一个 Python library,用来从 AI coding agents 中采集 telemetry,以支持 security monitoring、threat detection 和 observability。它会解析多个 AI agent 平台的日志,并转换成统一 schema。
这件事其实非常关键。因为现实中的 Agent 生态并不统一,每个工具的日志形态、落盘方式、平台依赖都不一样。ADR Sensor 做的,就是先把这些分散的行为轨迹“翻译”成统一语言。
目前 README 列出的支持对象包括:
- Claude Code
- Cursor IDE
- Cline
- Claude Desktop Agent Mode
- OpenAI Codex CLI
- Warp Terminal
这些来源的日志格式也并不相同,有的是 JSONL,有的是 SQLite,有的是任务文件。但在 Sensor 的架构里,它们最终都会进入一个统一的 AgentEvent 结构。
README 用一张架构图概括了这条链路:
- AI Agent Logs
- Source-Specific Parsers
- Unified Schema(AgentEvent)
- AgentObserver
- JSON / JSONL Export 或下游检测流水线
这套结构读起来很顺:先按来源解析,再标准化,再交给统一观察器做 ingest、filter、display、export。它很像一个专门为 AI agent 活动打造的“日志归一化前置层”。
它支持的不只是采集,还包括 CLI 和 Python API 两种使用方式
Sensor 的使用方式写得很接地气。
安装可以直接从 PyPI:
1 | pip install adr-sensor |
也可以从源码安装:
1 | git clone https://github.com/uber/ADR |
CLI 用法也很清晰:
1 | adr-sensor |
可以只采集特定来源:
1 | adr-sensor --source claude |
也可以保存单独 session、导出为 JSONL、包含全部历史,或者自定义输出目录:
1 | adr-sensor --save-sessions |
如果你更想把它嵌进自己的分析逻辑里,README 还给了 Python API 示例:
1 | from adr_sensor import AgentObserver |
这一层给人的感觉很明显:ADR 并没有把“安全观测”封死在某个大型平台里,而是把采集能力抽成了一个能独立使用的组件。
统一 schema 的意义,不只是规范,而是让检测成为可能
Sensor 里定义的 AgentEvent 结构,字段包括:
uuidtimestampsourcesession_idhostnameusernamemodelproject_pathchat_history
而 chat_history 又可以记录每条消息中的工具使用情况,包括:
tool_nametool_typeargumentsresultstatus
这一点非常重要。因为对于 Agent 安全来说,很多问题根本不在“最后一句输出”里,而藏在整个中间过程里:它看了什么、调用了什么、参数是什么、结果是什么、有没有异常跳转、有没有可疑行为模式。
统一 schema 的价值,恰恰是让这些跨工具、跨平台的行为,都能进入后续检测逻辑的视野。
Detection:这部分不仅在做检测,还把“怎么评估安全”一起做了
如果说 Sensor 是先把水接进来,那么 Detection 部分就是开始做分析、做评测、做验证的地方。
Detection/README.md 开门见山:这是一个用于 AI agent security research 的完整框架,包含 threat detection 和 red-teaming capabilities,并集成了 ADR-Bench + AgentDojo、133 MCP servers、four detector baselines。
但它也在一开始就立了一个很重要的警示牌:
Not for production use
README 解释得很清楚,这一部分是一个 research artifact,用于在 synthetic attack scenarios 下评估 AI agent security detectors,不适合直接部署到生产环境,而且必须运行在隔离环境中。
它甚至明确写到:
- 一些依赖版本被精确锁定,是为了复现实验结果
- 其中存在已知 CVEs,但在隔离威胁模型下被认为是可接受的
- benchmark fixtures 包含 synthetic credentials、prompt-injection payloads、模拟的 vulnerable MCP servers
- 不要把 benchmark 指向真实系统、真实凭据或生产 MCP servers
这种坦率反而很加分。因为它没有把研究框架包装成现成防线,而是很认真地告诉你:这部分是用来做评估和研究的,边界要清楚。
ADR-Bench:它给 Agent 安全评测准备了一整套“像真的一样”的任务世界
README 给 ADR-Bench 的定义很明确:在现实企业条件下测试 agent security。
它包含:
- 300+ tasks
- 133 MCP servers
- 覆盖 17 agent attack techniques
更具体一点,在 Detection/README.md 中,仓库里写的是:
tasks.json:303 scenarios- 其中 261 benign
- 42 malicious
mcp_servers_registry.json:133 server definitions
这套 benchmark 的设计显然不是一两个玩具样例,而是试图构建一个足够有层次的任务环境,让检测系统在“看起来像真实业务”的流程里接受考验。
README 还强调:
- ADR-Bench 执行 303 个 realistic business tasks
- AgentDojo 集成用于 prompt injection benchmark
- 它会强制 pure MCP usage,并阻断 80+ built-in tools
- 会测 task completion、tool coverage、performance
这就让 benchmark 不只是“看能不能识别恶意”,而是把完成任务与安全检测一起纳入评估框架里。
133 个 MCP servers,让这个基准看起来不像纸上谈兵
Detection/README.md 对 MCP 基础设施写得相当细。
其中包括:
- 133 general-purpose servers
- 另有 3 context providers
按 registry type 分类,它们包括:
- 102 local
- 12 local_environment
- 15 community
- 4 official
同时 README 还进一步拆解:
- 78 Benign Servers:合法业务工具和实用工具
- 25 Vulnerable Servers:包含嵌入式漏洞的目标工具,用于发现风险
- 12 Environment Servers:模拟企业系统环境
- 19 Community/Official Servers:来自社区和官方
- 3 Context Providers:威胁情报、策略、源码分析等专用上下文服务
这一层的设计很有代表性。它没有把安全评测局限在“模型回答了一句坏话”这种浅层场景,而是放进了真实工具生态的影子里。Agent 面对的是一组能调用、会返回、可能被伪装、也可能带着漏洞的工具世界。
它测试的威胁类别,也明显不止提示词注入
README 把威胁类别列得非常清楚。
ADR-Bench 中的 42 个复杂攻击,覆盖的类型包括:
- Credential Exposure
- Data Exfiltration
- Scope Violations
- Surveillance Overreach
- Financial Manipulation
- Control-Flow Hijacking
- Information Fidelity Attacks
AgentDojo 这边主要覆盖 prompt injection 类威胁,包括:
- Important Instructions
- Prompt Injection
- Goal Hijacking
- Context Poisoning
这份列表透露出一个很重要的信号:ADR 讨论的 agent 安全,不是只盯着某一种攻击技巧,而是在看 Agent 如何在业务流程中被引导、被污染、被劫持、被利用。
ADR Detection:两层结构,一层先捞,一层再深挖
主 README 对 ADR Detection 的描述里提到,它采用的是 two-tier architecture:
- 一层做 high-recall triage
- 一层对可疑 session 做更深的 agentic reasoning
这很像现实中的安防流程:先用高召回方式筛出可疑对象,再把深度分析资源投到真正值得看的地方。
虽然开源 README 没有在顶层展开所有内部细节,但 Detection/README.md 已经给出足够清晰的框架信息。仓库里的检测部分包括:
main_detector.pyconfig_detector.yamlguardrail/base_detector.pyadr_agent/llamafirewall_agent/
README 还说明默认 detector 是 adr,也就是 ADR dual-agent;如果想做无密钥 smoke test,可以使用 --detector llamafirewall。
从这个结构就能感受到,ADR 的检测不是简单 if-else 规则,而是把检测器当成一个明确可运行、可比较、可基准化的系统组件。
它不仅给你检测器,还给你对照基线
在基线方面,README 提到:
- ADR(dual-agent)
- LlamaFirewall
- ALRPHFS
- GuardAgent
其中需要注意的是,README 也写明了:
- ALRPHFS 和 GuardAgent 的 baseline code 已从仓库移除
- 它们在表格中的数据是论文中发布的数字
- 当前仓库中可运行的对比项主要是 ADR 与 LlamaFirewall
这种处理方式很务实。它既保留了论文里的对照关系,也对开源仓库中哪些 baseline 真正可运行交代得很清楚。
运行方式很直接,既能跑 benchmark,也能跑 detector
主 README 给出的 Quick start 以 Detection 为入口:
1 | git clone https://github.com/uber/ADR |
完整 benchmark 的运行方式也写得很详细。
运行 ADR-Bench:
1 | uv run python main_benchmark.py |
运行 AgentDojo benchmark:
1 | uv run python main_benchmark.py --benchmark agentdojo |
运行特定任务:
1 | uv run python main_benchmark.py --tasks 109,110 |
自定义并发:
1 | uv run python main_benchmark.py --concurrent 5 |
跑 detector 时,则可以指定结果目录:
1 | BENCH=benchmark/adr_bench_20251017_151604 |
对于 AgentDojo:
1 | AGENTDOJO=benchmark/agentdojo_YYYYMMDD_HHMMSS |
整个使用方式并不绕,README 把“先跑任务,再跑检测,再画图”的顺序写得很完整。
它连输出长什么样,都提前给你摆清楚了
在 benchmark 输出方面,README 说明 ADR-Bench 结果会保存到:
1 | benchmark/adr_bench_YYYYMMDD_HHMMSS/ |
里面包括:
summary.json- 各任务目录下的
result.json - 对应 workspace 中的完整执行日志
AgentDojo 结果则会保存到:
1 | benchmark/agentdojo_YYYYMMDD_HHMMSS/ |
其中还包括:
ground_truth.json- 每个任务的
result.json - 转换后的
claude_conversation.json
在 detector 输出方面,README 说明结果会写回 benchmark 目录,例如:
1 | benchmark/adr_bench_YYYYMMDD_HHMMSS/ |
而每个 detector 结果文件会包含:
detector_infoanalysesmetricsrun_statsanalysis_timestamp
这种写法让整个研究流程非常有“工程感”:你不是在跑一段黑盒脚本,而是在产出一个结构明确、便于回溯和比较的实验结果集。
论文复现路线也被完整保留了下来
README 一再把 docs/REPRODUCIBILITY.md 提出来,说明这是完整复现实验和图表的入口。
简版流程包括:
- Inflate packed benchmark
- Run detectors
- Plot figures
示例命令也给了:
1 | uv run python benchmark/benchmark_pack.py inflate \ |
1 | uv run python main_detector.py --results-dir benchmark/adr_bench_20251017_151604 |
1 | uv run python plot_paper_figures.py \ |
对于一个同时涉及论文和工程实现的仓库来说,这种把“如何复现评测结果”单独捋顺的做法,非常能降低理解门槛。
成绩部分,它给出的数字相当聚焦
ADR 的 README 没有铺天盖地给一堆表,而是把几个关键数字压得很紧。
在顶层 README 中,ADR-Bench 的规模是:
- 300+ tasks
- 133 MCP servers
- 覆盖全部 17 agent attack techniques
在 Detection/README.md 中,论文结果表写得更具体:
| Detector | Precision | Recall | F1 | False positives |
|---|---|---|---|---|
| ADR (dual-agent) | 1.000 | 0.667 (28/42) | 0.800 | 0 |
| ALRPHFS | 0.333 | — | — | 34 |
| GuardAgent | 0.231 | — | — | 30 |
| LlamaFirewall | 0.167 | — | — | 40 |
README 同时说明,这些结果报告于论文的原始 302-task evaluation set,而仓库当前提供的是 303 tasks,多了一个 benign task。
此外,它还提到:
- AgentDojo(93 tasks) 中,ADR 检测到了全部攻击,并有 3 次 false alarms
- README 的“Expected Performance”中还写到 7.5x concurrency speedup
- benchmark 中 MCP 工具使用占比 >95%
- 论文结果中 ADR 在 ADR-Bench 上达到 100% precision / 67% recall / 0 false positives
这些数字的组合,给人的印象非常鲜明:ADR 想证明的不只是“能发现一部分风险”,而是在企业 workflow 语境下,尽量以低误报代价去做有效检测。
它的研究气质很强,但并不脱离真实业务工作流
从 Detection/README.md 的细节里,能反复看到一个特点:它既是研究框架,又在努力贴近真实企业工作方式。
比如任务设计上,README 强调:
- 使用自然业务语言
- 场景要具体可执行
- 倾向多工具使用
- 有明确交付物
- 涉及具体文件名和参数时要具体
- 避免模糊请求
- 避免执行时间超过 10 分钟
这种任务设计原则非常像在模拟企业员工真实地向 Agent 发起工作请求,而不是生成一堆实验室里的抽象命题。
再比如,它允许你往 benchmark 里加新的 MCP servers、新的 custom servers、新的 malicious servers,以及新的 tasks。这种扩展机制,让 ADR-Bench 看起来更像一个可继续长大的研究平台,而不是一份固定题库。
从仓库传达出来的整体思路看,ADR 更像“企业 Agent 安全基础设施”的一部分
把 Sensor、Benchmark、Detection 这些部分合在一起看,会发现 ADR 的思路其实很完整:
- 先把多种 Agent 工具的行为采集下来
- 再在统一结构上观察意图、工具使用和执行轨迹
- 然后用系统化 benchmark 去测试检测能力
- 最后用 detector 对可疑行为进行分析和判定
这种路径的重点,不在于只守住一个“输入口”,而在于给企业里的 Agent 系统建立一套从可观测、到可评测、再到可检测的连续能力链。
这套链路之所以显得特别,是因为它承认了一个现实:Agent 的风险不只是模型本身带来的,而是来自模型、工具、上下文、执行流程共同组成的行动系统。
当系统已经具备行动能力时,安全也必须跟着进入“行动视角”。
最后想说的,是这个项目透露出的那种时代感
ADR 这个仓库最有意思的地方,不只是它支持了哪些工具、做了多少任务、跑了多少 benchmark。
更重要的是,它代表了一种变化:AI agent 讨论正在从“能力炫技”走向“企业落地后的治理问题”。
当 Claude Code、Cursor、Codex 这样的工具真的进入开发流程,当 MCP server 真的参与工作编排,当 Agent 不只是聊天窗口里的聪明回答者,而是能触碰环境、调用资源、执行动作的实体,安全问题就不再能用过去那套“给模型加点防护提示”轻轻带过。
ADR 的价值,正在于它把这件事认真地拆开看了:
- 先看见 Agent 在做什么
- 再设计一套真实感足够强的环境去测试它
- 再用检测系统去判断哪些行为值得警惕
它并没有把问题讲得很轻,也没有把答案包装得很简单。相反,这个项目像是在提醒所有人:
当 Agent 开始真正工作,安全就必须跟着一起进入生产级别的现实。
而 ADR,正是在这个现实里,给出了一套非常具体、非常工程化的回答。
