
字节笔记本
2026年8月24日
pgbot:只读单文件的 Postgres 体检工具,为 AI agent 而生
想知道一台 Postgres 现在健不健康,常规路子是装一套监控:collector、时序库、仪表盘,一样不能少。pgbot 走的是另一条路——一个静态二进制文件,只读连上去,读 Postgres 自带的统计视图,几秒钟吐出一份按严重程度分级的体检报告,还能告诉你跟上次比什么变了。它同时是给 AI agent 准备的:版本化的 JSON 契约、MCP 服务、Claude Code 插件都有。
项目简介
pgbot 用 Go 写的,Apache-2.0 开源,作者 pgrundev,2026 年 8 月中建仓,两周拿到 600 多 stars。定位是「数据库内的可观测性」:无 agent、无外部服务、整条链路没有任何写权限。支持 PostgreSQL 14 到 18(16-18 完整支持,14-15 尽力而为),Linux/macOS/Windows 的 amd64 和 arm64 都有。
它的几个设计立场值得单独说:
- 只读靠角色,不靠开关。安全边界是一个只有
pg_monitor权限的登录角色,工具本身在会话上再钉一层只读(default_transaction_read_only、15 秒语句超时、2 秒锁超时),每个探测都包在BEGIN READ ONLY里。纵深防御,角色是边界。 - 有记忆。每次运行写一份本地基线,从第三次运行起开始告诉你「什么变了、为什么要紧」:哪条查询变慢了、哪张表开始顺序扫描、哪个索引不再被用了。
- 发现是确定性的。所有 finding 在 Go 里从 SQL 算出来,可选的 AI 层只负责把它们讲成人话,从不生成 finding。
- 零部署。没有 collector、没有时序数据库、没有常驻服务,跑完就走。
- 为 agent 而生。
--json是带版本号、无 PII 的契约(当前 1.2.0,JSON Schema 随仓库发布),每一段都带 exactness 标签,消费方不会把累计值当成实时速率。
命令一览
| 命令 | 干什么 |
|---|---|
inspect | 完整体检报告,--full 加子系统状态板和分节详表 |
lint | 只查 schema,CI 空库上安全跑 |
init | 生成只读角色的建号 SQL,自己不执行 |
diff | 离线对比两份基线快照 |
why | 从基线历史解释一次回归:症状、机制、前因,带数字和发生时间 |
indexes / queries / tables / vacuum | 单项钻取:零扫描索引、最耗时语句、最大表、autovacuum 健康 |
advise | 经 planner 验证的缺索引建议(需要 hypopg) |
ask / explain | AI 把同一份 findings 讲成自然语言 |
explain-finding | 离线看某个 finding 的目录页 |
mcp | 以 MCP server 的形式把 findings 提供给 AI agent |
退出码是给脚本用的契约:0 干净、1 警告、2 严重、3 连不上、64 用法错误。输出格式除了终端文本,还有 json、sarif、junit、prometheus。
安装与首次使用
安装方式任选:
npx @pgbot/cli inspect "$DATABASE_URL" # 不装先用
curl -fsSL https://pgbot.dev/install | sh # cosign 签名 + 校验和
brew install pgrundev/tap/pgbot # Homebrew
go install github.com/pgrundev/pgbot/cmd/pgbot@latest
docker run --rm ghcr.io/pgrundev/pgbot inspect "$DATABASE_URL"一个坑提前说:npm 上裸名 pgbot 被命名相似规则拦了(离 got 太近),npx pgbot 会返回 E404,得用带 scope 的 npx @pgbot/cli。
首次使用先建只读角色。手写三行 SQL,或者让 pgbot init 按你的数据库厂商生成(包括装 pg_stat_statements 的步骤),生成后自己过目再执行:
CREATE ROLE pgbot_ro LOGIN PASSWORD '...';
GRANT pg_monitor TO pgbot_ro;
GRANT CONNECT ON DATABASE yourdb TO pgbot_ro;然后连上就跑。连接串的解析顺序是:参数、$DATABASE_URL、$PGBOT_DATABASE_URL。放环境变量里有个额外好处,密码不会进 shell 历史和 ps:
export DATABASE_URL="postgres://pgbot_ro@host:5432/db?sslmode=require"
pgbot inspect对数据库的开销控制得很紧:连接池上限 4 个,无长事务,一次完整 inspect 几秒钟完事,繁忙的主库上也能跑,它还会把自己的会话从报告里剔除,不把自己的足迹算成数据库的问题。
给 AI agent 用
这是 pgbot 下功夫最多的地方。pgbot mcp 在 stdio 上说 Model Context Protocol,暴露的全是只读工具:inspect、未用索引、top 查询、vacuum 健康、经 planner 验证的索引建议、索引与代码的相关性分级等。工具返回稳定的 JSON,不向模型暴露原始连接串和查询字面量。既然 pgbot 永不写,agent 通过它搞不坏任何东西。
配到 Claude Desktop/Code、Cursor 这类 MCP 客户端:
{
"mcpServers": {
"pgbot": {
"command": "pgbot",
"args": ["mcp"],
"env": { "DATABASE_URL": "postgres://pgbot_ro@host:5432/db" }
}
}
}再往上一层是配套的 postgres-diagnostics skill,教 agent 正确使用这些工具:尊重 caveat、绝不用 EXPLAIN ANALYZE、按影响排序、永不写。一条命令装进 Claude Code、Cursor 或 Codex:
npx skills add pgrundev/pgbotClaude Code 用户还有整包方案,仓库自身就是个插件市场,MCP 工具、skill、斜杠命令一次装齐:
claude plugin marketplace add pgrundev/pgbot
claude plugin install pgbot@pgbot装完有 /pg-health、/pg-slow、/pg-indexes 三个命令,直接问「我的 Postgres 健康吗」就行。
advise:索引建议经过 planner 验证
这个子命令值得单独一节。它从 pg_stat_statements 拿最慢的查询,从 planner 的顺序扫描过滤器里确定性地推导候选索引,然后用 hypopg 假设建索引、重新规划,只有 planner 真会切换过去且预估成本下降的才报给你:
⚑ public.orders
CREATE INDEX ON public.orders (customer_id, status);
helps: SELECT count(*) FROM orders WHERE customer_id = $1 AND status = $2
60 calls · 68% of DB time
planner confirmed: cost 4653 → 4.1 (−99.9%)全程不建任何真索引,只做规划不执行查询。需要 hypopg 扩展和 PostgreSQL 16+,缺什么它会告诉你装什么,不做别的动作。
CI 与导出
--fail-on 决定什么严重程度让退出码非零,配合格式化输出可以直接进流水线。--format=sarif 上传到 GitHub Security tab,官方给了现成的 Action:
- uses: pgrundev/pgbot@v1
with:
dsn: ${{ secrets.PGBOT_DSN }}
fail-on: critical审迁移 PR 的玩法比较巧:空库上全量检查会满屏误报,用 --profile=schema 只跑从目录能推导的检查,再配 --fail-on-new 只对 PR 新引入的 finding 报错,存量问题不拦路。Prometheus 用户用 --format=prometheus 输出 textfile collector 格式,cron 定时跑,刻意不做常驻进程。
边界在哪
README 里自己说得很清楚:pgbot 是你运行的时间点诊断,不是你运维的监控平台。要仪表盘、告警、长留存、多机聚合,该用 pganalyze、Percona PMM、pgwatch 还是得用,pgbot 不替代它们。适合 pgbot 的时刻是:十秒内要个答案、不想部署任何东西、排查一台不归你管的库,或者 AI agent 需要能推理的结构化 Postgres 数据。另外主机层指标(CPU、磁盘 IOPS)走 SQL 连接拿不到,RDS 上这些在 CloudWatch 里。
注意事项
- 一定要用
pg_monitor角色,别用超级用户;权限不够时 pgbot 会在连接时指出该跑哪条 GRANT explain和ask是唯二出网的命令,发的是无 PII 的 Context(查询文本做了参数归一化,连接串在所有输出里脱敏);不想用 AI 层可以完全不配 key- 本地 Docker 里的库要用
127.0.0.1连,别用localhost,IPv6 解析会让连接卡十秒 npx pgbot是 E404,记得用npx @pgbot/cli- 基线存在
~/.local/state/pgbot/,七天全分辨率加九十天小时级汇总,上限 100MB,随时可以删 - 项目状态是 beta,
--json契约已版本化,但人读的终端输出不算稳定接口,写脚本请解析--json
项目链接
- GitHub 仓库:https://github.com/pgrundev/pgbot
- 安装脚本:https://pgbot.dev/install