Hotdry.
ai-systems

用 400 行 SQL 在 PostgreSQL 行内嵌入 AI 代理:pgclaw 设计与落地清单

本文深入解析 pgclaw 扩展如何通过约 400 行 SQL 代码在 PostgreSQL 每行中嵌入 AI 代理,探讨其架构设计、应用场景、配置参数与性能考量,为开发者提供可落地的轻量级行内智能方案。

在传统架构中,AI 代理(Agent)通常作为独立服务运行,通过 API 与数据库交互。这种分离带来了网络延迟、数据一致性挑战以及复杂的运维负担。能否将智能直接嵌入数据存储层,让每一行数据都拥有自主决策能力?开源扩展 pgclaw 给出了一个大胆的答案:通过约 400 行 SQL 代码,在 PostgreSQL 的每一行中嵌入一个轻量级 AI 代理(Clawdbot),实现数据与智能的紧耦合。

核心理念:行内智能体

pgclaw 的核心创新在于引入了 claw 数据类型。你可以像定义 INTEGERTEXT 一样,在表中定义一个 claw 列。该列的值不是一个简单的标量,而是一个绑定到该行数据的 AI 代理实例。这个代理可以是一个简单的 LLM 提示,也可以是一个具备状态、记忆甚至代码执行能力的复杂 “OpenClaw” 代理。

正如项目发起人在 Hacker News 上所述,其初衷是探索 “如果在 Postgres 表的每一行都有一个 AI 助手会怎样”。pgclaw 试图将代理的运行时完全内化到数据库进程中,利用 PostgreSQL 强大的扩展机制,避免引入外部服务依赖。

架构解析:400 行 SQL 如何实现

pgclaw 的实现巧妙利用了 PostgreSQL 的多项内置功能,构成了一个轻量而完整的代理运行时:

  1. 自定义类型与函数claw 类型及其构造函数是扩展的入口。用户通过 claw('提示文本')claw(agent => '预定义代理') 来初始化代理。
  2. 触发器与队列:对包含 claw 列的表执行 claw_watch() 后,会自动创建触发器。当行被插入或更新时,触发器将相关数据(包括代理配置和行内容)作为任务插入到内置的 claw.queue 表中。
  3. 后台工作器(Background Worker):这是 pgclaw 的 “引擎”。一个常驻的 PostgreSQL 后台工作器定期轮询 claw.queue,取出待处理任务。根据代理类型,它执行不同逻辑:
    • 简单 LLM 代理:根据代理配置和行数据构建提示词,通过 rig 库调用配置的 LLM 提供商(如 Anthropic、OpenAI、Ollama 等)。
    • Claude Code 代理:为代理创建独立的工作空间目录,生成配置文件(如 SOUL.md),并通过 claude-agent-sdk 启动 Claude Code 进程,使其具备读写文件、运行代码的能力。
  4. 响应解析与回写:LLM 或 Claude Code 的响应被期望包含一个简单的 JSON 对象,如 {"priority": "critical", "summary": "登录页面发生 500 错误,需立即处理"}。后台工作器解析此响应,并生成相应的 UPDATE 语句将结果写回原行。
  5. 状态管理:代理的对话历史被自动记录在 claw.history 表中,支持多轮交互。有状态的代理还可以通过响应中的 {"__memory": {...}} 字段更新自己的记忆。

整个流程严格在数据库事务(ACID)边界内运行,确保了处理过程的一致性。项目代码精炼,核心逻辑集中于 SQL 函数和 PL/pgSQL 过程,充分展示了 PostgreSQL 作为 “可编程数据库” 的威力。

可落地应用场景与参数清单

pgclaw 并非玩具,其设计面向具体的自动化场景。以下是可直接复用的应用模式与关键配置参数:

场景一:智能工单自动分类与摘要

-- 1. 定义分类代理
INSERT INTO claw.agents (id, soul, instructions) VALUES (
    'ticket-triage',
    '你是一个细致的支持工单分类员。',
    '阅读工单内容。设置优先级(low/medium/high/critical)并生成一句话摘要。如果不确定,设置为 medium 并在摘要中说明。'
);

-- 2. 创建工单表并绑定代理
CREATE TABLE tickets (
    id       serial PRIMARY KEY,
    title    text,
    body     text,
    priority text,   -- 代理将更新此字段
    summary  text,   -- 代理将更新此字段
    agent    claw DEFAULT claw(agent => 'ticket-triage') -- 每行绑定一个代理
);
SELECT claw_watch('tickets'); -- 启用监听

-- 3. 插入工单,代理自动运行
INSERT INTO tickets (title, body) VALUES ('登录故障', '登录页面报 500 错误');
-- 约 1-2 秒后,查询该行,priority 和 summary 字段已被填充。

关键参数

  • 模型选择:通过 pgclaw.default_model 配置默认模型,或在 claw() 构造函数中指定 model => 'claude-sonnet'。对于分类任务,中等规模模型(如 claude-sonnet, gpt-4o-mini)在成本与效果间较平衡。
  • 超时控制:当前版本未显式暴露超时参数。在实际部署中,需注意 LLM API 调用可能因网络或服务方延迟而阻塞后台工作器。建议初期设置较宽松的 statement_timeout 用于测试。
  • 错误处理:代理执行失败时,错误信息会记录在 claw.queueclaw.history 中。需要建立监控机制,定期检查失败任务。

场景二:具备代码执行能力的自动化工作流

对于需要执行代码的任务(如自动生成 SQL 迁移、运行单元测试),可以启用 Claude Code 代理:

-- 1. 定义工程师代理,授予工作空间
INSERT INTO claw.agents (id, soul, instructions, workspace) VALUES (
    'engineer',
    '你是一名高级工程师。编写清晰、经过测试的代码。',
    '实现需求变更。运行测试。根据测试结果将状态更新为 pass 或 fail。',
    'auto' -- 自动创建工作空间目录
);

-- 2. 创建任务表
CREATE TABLE tasks (
    id serial PRIMARY KEY,
    requirement text,  -- 任务描述
    status text DEFAULT 'pending',
    code_diff text,    -- 代理生成的代码差异
    agent claw DEFAULT claw(agent => 'engineer')
);
SELECT claw_watch('tasks');

关键参数

  • 工作空间路径:通过 pgclaw.workspace_dir 配置基础目录。'auto' 模板会生成 {workspace_dir}/{agent_id}/{table}/{primary_key}/ 的路径。确保数据库进程对该目录有读写权限。
  • 资源隔离:每个代理在独立的工作空间运行,但共享数据库进程资源。需关注长时间运行或资源密集的代码任务对数据库整体性能的影响。

场景三:多通道会话机器人

pgclaw 支持通过通道(channel)将外部请求路由到指定的代理,实现聊天机器人功能:

-- 1. 定义支持机器人代理
INSERT INTO claw.agents (id, soul, instructions) VALUES (
    'support-bot',
    '你是 Acme 公司的支持机器人。',
    '帮助用户解决订单相关问题。'
);

-- 2. 绑定通道(例如 Telegram)
INSERT INTO claw.bindings (channel, agent_id) VALUES ('telegram', 'support-bot');

-- 3. 发送消息到通道
SELECT claw_route('telegram', '*', 'user123', NULL, '我的订单延迟了');
-- 响应可以从 claw.outbox 表中获取

关键参数

  • 心跳机制:通过 claw.heartbeats 表可以设置代理定期执行(如每 30 分钟),适用于定时检查类任务。
  • 会话保持claw_route 会自动关联用户 ID (user123),后续同一用户的对话会共享上下文历史,实现连贯的多轮交互。

配置清单与部署要点

  1. 安装前提

    • Rust 工具链(用于编译扩展)。
    • PostgreSQL 17 开发头文件。
    • 执行 cargo pgrx install 编译并安装扩展。
  2. 必要配置postgresql.conf):

    shared_preload_libraries = 'pgclaw'  # 预加载扩展
    pgclaw.api_key = 'sk-ant-...'        # LLM 提供商 API 密钥
    pgclaw.database = 'mydb'             # 后台工作器运行的数据库
    
  3. 提供商配置(示例):

    # 使用 Anthropic (默认)
    pgclaw.api_provider = 'anthropic'
    pgclaw.default_model = 'claude-sonnet-4-5-20250929'
    
    # 使用本地 Ollama
    pgclaw.api_provider = 'ollama'
    pgclaw.api_key = ''                  # 本地无需密钥
    pgclaw.default_model = 'llama3.1'
    
    # 使用自定义 OpenAI 兼容端点(如 vLLM)
    pgclaw.api_provider = 'openai'
    pgclaw.api_url = 'http://localhost:8000/v1'
    
  4. 监控与调试

    • 查询 claw.queue 查看待处理任务。
    • 查询 claw.history 查看所有代理执行的历史记录和完整对话。
    • 检查 PostgreSQL 日志,关注后台工作器的错误信息。

局限性、性能考量与未来展望

pgclaw 是一个令人兴奋的实验性项目,但在投入生产前需清醒认识其边界:

  • 性能:每个行代理的处理涉及 LLM API 调用,延迟在秒级。这决定了它适用于异步、低频率的自动化任务(如工单分类、内容审核、报告生成),而非高并发实时接口。一条 Hacker News 评论也指出:“我无法想象它目前的生产性能足够好,但…… 哇。” 这反映了社区对其概念创新性的赞赏与对性能的合理担忧。
  • 成熟度:项目处于早期阶段,版本迭代可能较快,缺乏大规模生产验证。
  • 资源消耗:每个活跃的 Claude Code 代理会启动独立进程并占用工作空间。需要监控数据库主机的内存和 CPU 使用情况。
  • 安全性:代理具有根据指令更新数据库字段的能力,需严格审查代理的 instructions,避免产生非预期的数据修改。启用代码执行能力时,风险更高,必须在隔离环境中测试。

尽管存在限制,pgclaw 所代表的 “行内智能” 范式为数据库与 AI 的融合开辟了新路径。未来的演进可能包括:更精细的流控与优先级队列、对代理执行资源的配额管理、更丰富的内置工具函数,以及与其他 PostgreSQL 生态(如逻辑复制、FDW)的集成。

结语

pgclaw 用约 400 行 SQL 代码挑战了 “AI 代理必须作为外部服务” 的固有认知。它将智能体轻量化并嵌入数据行的设计,为需要数据紧耦合智能的应用场景(如自动化工作流、个性化内容处理、内部工具助手)提供了一个极具创意的原型。开发者可以将其视为一个强大的 “数据库内自动化触发器”,在明确性能边界和风险的前提下,谨慎地用于特定场景,能够显著简化架构,实现 “智能就在数据中” 的愿景。

本文参考了 calebwin/pgclaw GitHub 仓库 的文档与代码,以及相关的 Hacker News 讨论

查看归档