Skip to content
Learn Agentic AI
Learn Agentic AI9 min read3 views

Building a Pricing Agent: Dynamic Pricing and Quote Generation with AI

Implement an AI pricing agent that applies dynamic pricing rules, generates professional quotes, performs competitor price analysis, and handles discount approval workflows.

The Complexity of B2B Pricing

B2B pricing is rarely as simple as a price tag. Deals involve volume discounts, contract length tiers, bundle pricing, competitive matching, and approval chains. Sales reps spend hours assembling quotes manually, and inconsistent pricing erodes margins. An AI pricing agent codifies your pricing rules, generates professional quotes instantly, and enforces approval workflows for discounts that exceed predefined thresholds.

Pricing Rule Engine

The foundation is a rule engine that encodes your pricing logic. Rules are composable — each rule can modify the base price, and they apply in order.

flowchart TD
    START["Building a Pricing Agent: Dynamic Pricing and Quo…"] --> A
    A["The Complexity of B2B Pricing"]
    A --> B
    B["Pricing Rule Engine"]
    B --> C
    C["Applying Pricing Rules"]
    C --> D
    D["Competitor Price Analysis"]
    D --> E
    E["Quote Generation"]
    E --> F
    F["Discount Approval Workflow"]
    F --> G
    G["FAQ"]
    G --> DONE["Key Takeaways"]
    style START fill:#4f46e5,stroke:#4338ca,color:#fff
    style DONE fill:#059669,stroke:#047857,color:#fff
from dataclasses import dataclass, field
from typing import Optional
from enum import Enum


class DiscountType(Enum):
    PERCENTAGE = "percentage"
    FIXED = "fixed"


@dataclass
class PricingRule:
    name: str
    discount_type: DiscountType
    value: float
    condition: str  # e.g., "quantity >= 100"
    max_discount_pct: float = 30.0  # ceiling to protect margins
    requires_approval: bool = False


@dataclass
class LineItem:
    product_id: str
    product_name: str
    base_price: float
    quantity: int
    applied_rules: list[str] = field(default_factory=list)
    final_unit_price: float = 0.0

    @property
    def line_total(self) -> float:
        return self.final_unit_price * self.quantity


@dataclass
class Quote:
    quote_id: str
    customer_name: str
    items: list[LineItem]
    valid_until: str
    notes: str = ""
    requires_approval: bool = False
    approval_reason: Optional[str] = None

    @property
    def total(self) -> float:
        return sum(item.line_total for item in self.items)


def evaluate_condition(condition: str, context: dict) -> bool:
    """Safely evaluate a pricing condition against context."""
    allowed_names = {
        "quantity": context.get("quantity", 0),
        "contract_months": context.get("contract_months", 1),
        "total_value": context.get("total_value", 0),
        "is_new_customer": context.get("is_new_customer", False),
        "customer_tier": context.get("customer_tier", "standard"),
    }
    try:
        return bool(eval(condition, {"__builtins__": {}}, allowed_names))
    except Exception:
        return False

Applying Pricing Rules

The pricing engine iterates through rules, applies matching discounts, and tracks which rules were used for audit purposes.

PRICING_RULES = [
    PricingRule(
        name="Volume 50+",
        discount_type=DiscountType.PERCENTAGE,
        value=10.0,
        condition="quantity >= 50",
    ),
    PricingRule(
        name="Volume 200+",
        discount_type=DiscountType.PERCENTAGE,
        value=20.0,
        condition="quantity >= 200",
    ),
    PricingRule(
        name="Annual contract",
        discount_type=DiscountType.PERCENTAGE,
        value=15.0,
        condition="contract_months >= 12",
    ),
    PricingRule(
        name="Enterprise deep discount",
        discount_type=DiscountType.PERCENTAGE,
        value=35.0,
        condition="quantity >= 500 and contract_months >= 24",
        requires_approval=True,
    ),
]


def calculate_price(
    base_price: float,
    quantity: int,
    context: dict,
    rules: list[PricingRule] = PRICING_RULES,
) -> tuple[float, list[str], bool]:
    """Apply pricing rules and return final unit price, applied rules, approval flag."""
    ctx = {**context, "quantity": quantity}
    total_discount_pct = 0.0
    applied = []
    needs_approval = False

    for rule in rules:
        if not evaluate_condition(rule.condition, ctx):
            continue
        if rule.discount_type == DiscountType.PERCENTAGE:
            total_discount_pct += rule.value
        if rule.requires_approval:
            needs_approval = True
        applied.append(rule.name)

    # Cap total discount
    max_cap = max((r.max_discount_pct for r in rules), default=30.0)
    total_discount_pct = min(total_discount_pct, max_cap)

    final_price = base_price * (1 - total_discount_pct / 100)
    return round(final_price, 2), applied, needs_approval

Competitor Price Analysis

When a prospect mentions a competitor's price, the agent should be able to assess the competitive position and recommend a response.

from openai import AsyncOpenAI
import json

client = AsyncOpenAI()

COMPETITOR_ANALYSIS_PROMPT = """A prospect mentioned a competitor's pricing.

Our product: {our_product} at ${our_price}/unit
Competitor: {competitor} at ${competitor_price}/unit
Deal size: {quantity} units, {contract_months}-month contract
Customer tier: {customer_tier}

Our differentiation points:
{differentiators}

Return JSON with:
- "price_gap_pct": percentage difference
- "recommendation": "match", "hold", or "counter"
- "suggested_price": our recommended price per unit
- "talk_track": 2-3 sentences the sales rep can use
- "max_discount_pct": maximum discount percentage to recommend
"""


async def analyze_competitor_price(
    our_product: str,
    our_price: float,
    competitor: str,
    competitor_price: float,
    quantity: int,
    contract_months: int,
    customer_tier: str,
    differentiators: str,
) -> dict:
    response = await client.chat.completions.create(
        model="gpt-4o",
        response_format={"type": "json_object"},
        messages=[
            {"role": "system", "content": "Return valid JSON only."},
            {
                "role": "user",
                "content": COMPETITOR_ANALYSIS_PROMPT.format(
                    our_product=our_product,
                    our_price=our_price,
                    competitor=competitor,
                    competitor_price=competitor_price,
                    quantity=quantity,
                    contract_months=contract_months,
                    customer_tier=customer_tier,
                    differentiators=differentiators,
                ),
            },
        ],
    )
    return json.loads(response.choices[0].message.content)

Quote Generation

The agent assembles all pricing decisions into a professional quote document.

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

import uuid
from datetime import datetime, timedelta


async def generate_quote(
    customer_name: str,
    items: list[dict],
    context: dict,
) -> Quote:
    """Generate a complete quote with pricing rules applied."""
    line_items = []
    needs_approval = False

    for item in items:
        final_price, applied_rules, approval = calculate_price(
            base_price=item["base_price"],
            quantity=item["quantity"],
            context=context,
        )
        if approval:
            needs_approval = True

        line_items.append(LineItem(
            product_id=item["product_id"],
            product_name=item["product_name"],
            base_price=item["base_price"],
            quantity=item["quantity"],
            applied_rules=applied_rules,
            final_unit_price=final_price,
        ))

    valid_until = (datetime.utcnow() + timedelta(days=30)).strftime("%Y-%m-%d")

    quote = Quote(
        quote_id=f"Q-{uuid.uuid4().hex[:8].upper()}",
        customer_name=customer_name,
        items=line_items,
        valid_until=valid_until,
        requires_approval=needs_approval,
        approval_reason="Deep discount rules triggered" if needs_approval else None,
    )
    return quote


def format_quote_text(quote: Quote) -> str:
    lines = [
        f"QUOTE: {quote.quote_id}",
        f"Customer: {quote.customer_name}",
        f"Valid until: {quote.valid_until}",
        "",
        "Line Items:",
    ]
    for item in quote.items:
        savings = (item.base_price - item.final_unit_price) * item.quantity
        lines.append(
            f"  {item.product_name}: {item.quantity} x "
            f"${item.final_unit_price:.2f} = ${item.line_total:.2f}"
            f" (saves ${savings:.2f})"
        )
        if item.applied_rules:
            lines.append(f"    Discounts: {', '.join(item.applied_rules)}")
    lines.append(f"\nTOTAL: ${quote.total:.2f}")
    if quote.requires_approval:
        lines.append(f"\n** REQUIRES APPROVAL: {quote.approval_reason} **")
    return "\n".join(lines)

Discount Approval Workflow

Discounts that exceed thresholds need manager approval before the quote can be sent. The agent routes these through an approval queue.

async def submit_for_approval(quote: Quote, db_pool, notifier):
    async with db_pool.acquire() as conn:
        await conn.execute(
            """INSERT INTO quote_approvals
               (quote_id, customer, total, reason, status, requested_at)
               VALUES ($1, $2, $3, $4, 'pending', NOW())""",
            quote.quote_id, quote.customer_name,
            quote.total, quote.approval_reason,
        )
    await notifier.send(
        channel="#pricing-approvals",
        message=(
            f"Quote {quote.quote_id} for {quote.customer_name} "
            f"(${quote.total:.2f}) needs approval.\n"
            f"Reason: {quote.approval_reason}"
        ),
    )

FAQ

How do I prevent the pricing agent from offering discounts that are too deep?

Implement hard caps at the rule engine level using the max_discount_pct field. Even if multiple rules stack, the total discount cannot exceed the cap. Additionally, any discount above a configurable threshold (e.g., 25 percent) should automatically flag the quote for manager approval rather than applying it directly.

How do I handle pricing for custom or non-standard configurations?

Define a fallback rule that routes non-standard requests to a human pricing specialist. The agent collects the requirements in a structured format — quantities, contract terms, special needs — and creates an approval ticket with all the context the pricing team needs to respond quickly.

Should I let the LLM set prices directly?

Never. The LLM should recommend pricing strategies and generate talk tracks, but actual price calculations must come from your deterministic rule engine. LLMs are not reliable for precise arithmetic, and pricing errors have direct financial consequences. Use the LLM for analysis and presentation, not for the math.


#DynamicPricing #QuoteGeneration #PricingStrategy #SalesAI #Python #AgenticAI #LearnAI #AIEngineering

Share
C

Written by

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.

Related Articles You May Like

AI Interview Prep

7 AI Coding Interview Questions From Anthropic, Meta & OpenAI (2026 Edition)

Real AI coding interview questions from Anthropic, Meta, and OpenAI in 2026. Includes implementing attention from scratch, Anthropic's progressive coding screens, Meta's AI-assisted round, and vector search — with solution approaches.

Learn Agentic AI

AI Agents for Sales: Automated Lead Qualification, Batch Calling, and Pipeline Management

How AI sales agents automate BDR workflows with inbound lead qualification, outbound batch calling campaigns, real-time transcription, lead scoring, and CRM integration patterns.

Learn Agentic AI

Building a Multi-Agent Data Pipeline: Ingestion, Transformation, and Analysis Agents

Build a three-agent data pipeline with ingestion, transformation, and analysis agents that process data from APIs, CSVs, and databases using Python.

Learn Agentic AI

Building a Research Agent with Web Search and Report Generation: Complete Tutorial

Build a research agent that searches the web, extracts and synthesizes data, and generates formatted reports using OpenAI Agents SDK and web search tools.

Learn Agentic AI

OpenAI Agents SDK in 2026: Building Multi-Agent Systems with Handoffs and Guardrails

Complete tutorial on the OpenAI Agents SDK covering agent creation, tool definitions, handoff patterns between specialist agents, and input/output guardrails for safe AI systems.

Learn Agentic AI

LangGraph Agent Patterns 2026: Building Stateful Multi-Step AI Workflows

Complete LangGraph tutorial covering state machines for agents, conditional edges, human-in-the-loop patterns, checkpointing, and parallel execution with full code examples.