COMPARISON

    xBPP + OpenAI Agents SDK

    Payment Governance for GPT Agents

    The OpenAI Agents SDK gave a lot of teams a clean way to build multi-step GPT agents with tool calls, handoffs, and structured outputs. What it deliberately doesn't give you is a payment policy layer - because, like every good SDK, it's focused on the problem it solves and leaves governance to the application layer.

    If your OpenAI-based agent is about to spend money, this is the page for you.

    Not a replacement, a composition

    xBPP and the OpenAI Agents SDK don't overlap. One builds agents, the other governs what agents are allowed to spend.

    • OpenAI Agents SDK handles the agent loop: tool calling, handoffs between sub-agents, message history, structured outputs. It's the scaffolding for a GPT-based agent.
    • xBPP handles policy: when one of those tools is a pay() or transfer() function, xBPP decides whether each call actually executes.

    Think of xBPP as middleware that runs at the moment the SDK hands a tool call back to your code for execution. Your code already has to decide what to do with tool outputs - xBPP just gives you a better way to handle the ones that move money.

    Integration shape

    Here's the pattern, kept close to the idiomatic OpenAI Agents SDK shape. The pay tool is defined normally; xBPP lives in the tool's implementation.

    import { Agent, tool } from '@openai/agents'
    import { evaluate } from '@vanar/xbpp'
    import policy from './policies/openai-agent.json'
    
    const payTool = tool({
      name: 'pay',
      description: 'Send a USDC payment to a recipient',
      parameters: {
        type: 'object',
        properties: {
          amount: { type: 'number' },
          recipient: { type: 'string' }
        },
        required: ['amount', 'recipient']
      },
      async execute({ amount, recipient }) {
        // xBPP runs before any money moves
        const verdict = evaluate(
          { amount, currency: 'USDC', recipient },
          policy
        )
    
        if (verdict.decision === 'BLOCK') {
          return {
            status: 'blocked',
            reasons: verdict.reasons,
            message: verdict.message
          }
        }
    
        if (verdict.decision === 'ESCALATE') {
          const approved = await humanApproval.request({ amount, recipient, verdict })
          if (!approved) return { status: 'declined_by_human' }
        }
    
        // ALLOW (or escalation approved): execute the payment
        const result = await executePayment({ amount, recipient })
        return { status: 'sent', txHash: result.hash }
      }
    })
    
    const agent = new Agent({
      name: 'research-agent',
      model: 'gpt-4o',
      instructions: 'You help users by buying data reports and API credits.',
      tools: [payTool]
    })

    Everything that isn't the evaluate() call is plain OpenAI Agents SDK code. If you remove the xBPP line, the agent still works - it just has no policy layer. That's the point: xBPP is additive and non-invasive.

    Why this pattern beats prompt-based limits

    The default instinct on OpenAI-based agents is to put spending rules in the instructions field:

    Never spend more than $100 per day. Never pay recipients you haven't
    seen before. If you're unsure, ask the user.

    This is not a security control. It's a suggestion, and the model is free to ignore it under the wrong inputs. Specifically:

    1. Prompt injection. A retrieved document or tool result can contain instructions that override your original rules. This has been a demonstrated attack for years.
    2. Context drift. On long conversations, early-system-prompt rules lose weight relative to recent user messages.
    3. Non-determinism. Even without injection, the model's compliance with instructions is probabilistic. "Never" means "almost never" in practice.
    4. No audit trail. When something goes wrong, you can look at the transcript and guess - but there's no structured record of which rules fired and why.

    xBPP runs deterministically outside the model. Same input always produces the same verdict. Every verdict is logged with structured reason codes. A policy change is a config change, not a prompt edit.

    Use prompt instructions to guide the model toward sensible behavior. Use xBPP to enforce the rules that actually matter.

    Feeding the verdict back to the agent

    One of the nicer properties of tool-returning-structured-data is that you can let the agent reason about a policy block. When pay() returns { status: 'blocked', reasons: [...] }, the SDK feeds that back into the next model turn, and the agent can:

    • Retry with a smaller amount
    • Pick a different recipient
    • Explain to the user what happened and ask for guidance
    • Fall back to a different plan

    No exception handling, no brittle retry loops, no "agent got confused and crashed" failure mode. Just structured feedback the model can reason about.

    Handoffs and sub-agents

    If your agent uses the SDK's handoff feature to delegate work to a sub-agent, xBPP still works the same way - wherever the payment tool is defined, wrap its execution in evaluate(). Some patterns:

    • Per-agent policies. The main orchestrator agent might have a $10k/day budget, while a "researcher" sub-agent gets $500/day. Each agent loads its own policy file.
    • Hierarchical escalation. Sub-agent BLOCK verdicts can be returned as tool results to the orchestrator, which can then decide whether to escalate to a human or retry with different parameters.
    • Shared budget. Multiple sub-agents can share a single policy file with a global counter, so the total across all sub-agents stays within your limit.

    Feature comparison

    xBPPOpenAI Agents SDK
    CategoryPolicy engineAgent framework
    Lives whereInside tool executionAround tool execution
    Decides...Whether a payment runsWhen to call tools, handoff logic
    DeterministicYesNo (model output)
    Declarative policyYes (JSON)No (code + prompts)
    Audit trailStructured verdict logMessage + trace logs
    Prompt-injection-resistantYesNo
    Chain / railAgnosticAgnostic via custom tools
    Runtime depsZeroOpenAI SDK

    When to use xBPP with OpenAI Agents SDK

    Use xBPP any time your agent can:

    • Send x402 payments
    • Move crypto / stablecoins on-chain
    • Call Stripe, PayPal, or any payment API
    • Purchase API credits, reports, or data
    • Pay for compute or infra
    • Approve or initiate any financial transaction

    Skip xBPP if your agent is purely informational (search, summarize, answer questions). The value shows up at the exact moment your agent's decisions start costing money.

    FAQ

    Does xBPP work with the Assistants API?

    Yes. Wrap the payment tool's implementation in evaluate() the same way. The agent framework above it doesn't matter.

    Does xBPP work with function calling directly (without the Agents SDK)?

    Yes. Function calling returns a structured tool call that you execute in your own code - that's where xBPP goes.

    Can I use different policies for different agents in the same app?

    Yes. Each tool instance can load its own policy file. The SDK has no global state that would interfere.

    Does xBPP log to OpenAI's tracing?

    Not by default, but you can emit the verdict as a structured log line that your existing tracing stack picks up. Most teams integrate it with whatever observability they already run.

    Is there a performance cost?

    Sub-millisecond. xBPP evaluation is local, synchronous, and has no network calls or external state.

    Further reading