Skip to main content
This example demonstrates building a production-ready customer support agent using PromptSmith with the Vercel AI SDK.

What You’ll Build

A customer support agent that can:
  • Search a product knowledge base
  • Look up order information
  • Answer customer questions with context-aware responses
  • Follow company guidelines and constraints

Prerequisites

npm install promptsmith-ts ai @ai-sdk/openai zod
Set up your OpenAI API key:
export OPENAI_API_KEY="your-api-key-here"

Complete Example

import { createPromptBuilder } from "promptsmith-ts/builder";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";

// Mock knowledge base search
async function searchKnowledgeBase(query: string, category?: string) {
  // In production, this would query your actual knowledge base
  const mockResults = [
    {
      id: "kb-001",
      title: "How to return a product",
      content: "Products can be returned within 30 days of purchase...",
      category: "returns",
    },
    {
      id: "kb-002",
      title: "Shipping information",
      content: "Standard shipping takes 5-7 business days...",
      category: "shipping",
    },
  ];

  return mockResults.filter(
    (result) =>
      result.content.toLowerCase().includes(query.toLowerCase()) &&
      (!category || result.category === category)
  );
}

// Mock order lookup
async function lookupOrder(orderId: string) {
  // In production, this would query your order database
  return {
    orderId,
    status: "shipped",
    trackingNumber: "1Z999AA10123456784",
    estimatedDelivery: "2026-03-05",
    items: [
      { name: "Wireless Headphones", quantity: 1, price: 79.99 },
    ],
  };
}

async function main() {
  // Build the customer support agent
  const supportAgent = createPromptBuilder()
    .withIdentity(
      "You are a helpful customer support representative for TechStore, an electronics retailer"
    )
    .withCapabilities([
      "Answer questions about products and policies",
      "Help customers track their orders",
      "Provide information about returns and exchanges",
      "Assist with technical product questions",
    ])
    .withTool({
      name: "search_knowledge_base",
      description: "Search the company knowledge base for information about products, policies, and procedures",
      schema: z.object({
        query: z.string().describe("The search query"),
        category: z
          .enum(["products", "shipping", "returns", "technical"])
          .optional()
          .describe("Optional category to filter results"),
      }),
      execute: async ({ query, category }) => {
        return await searchKnowledgeBase(query, category);
      },
    })
    .withTool({
      name: "lookup_order",
      description: "Look up order status and tracking information by order ID",
      schema: z.object({
        orderId: z.string().describe("The order ID to look up"),
      }),
      execute: async ({ orderId }) => {
        return await lookupOrder(orderId);
      },
    })
    .withConstraint("must", [
      "Always be polite and professional",
      "Search the knowledge base before providing policy information",
      "Verify order IDs before looking them up",
      "Apologize for any inconvenience the customer has experienced",
    ])
    .withConstraint("must_not", [
      "Make promises about refunds without checking policies",
      "Share other customers' information",
      "Provide technical support for products not sold by TechStore",
    ])
    .withGuardrails()
    .withTone("Empathetic, professional, and solution-oriented");

  // Use the agent to respond to a customer inquiry
  const { text } = await generateText({
    model: openai("gpt-4"),
    ...supportAgent.toAiSdk(),
    prompt: "Hi, I ordered some headphones last week (order #12345) and I'm wondering when they'll arrive?",
  });

  console.log("Agent Response:");
  console.log(text);
}

main().catch(console.error);

Step-by-Step Walkthrough

1

Define Tool Functions

Create the functions that your agent will use to access data:
async function searchKnowledgeBase(query: string, category?: string) {
  // Query your knowledge base API
  // Returns relevant articles and documentation
}

async function lookupOrder(orderId: string) {
  // Query your order management system
  // Returns order status and tracking info
}
In production, these functions would connect to your actual databases and APIs.
2

Create the Agent Builder

Initialize the prompt builder and set the agent’s identity:
const supportAgent = createPromptBuilder()
  .withIdentity(
    "You are a helpful customer support representative for TechStore"
  )
The identity establishes who the agent is and what company it represents.
3

Define Capabilities

Specify what the agent can do:
.withCapabilities([
  "Answer questions about products and policies",
  "Help customers track their orders",
  "Provide information about returns and exchanges",
  "Assist with technical product questions",
])
Capabilities help the agent understand its scope of responsibility.
4

Add Tools

Add the knowledge base search and order lookup tools:
.withTool({
  name: "search_knowledge_base",
  description: "Search the company knowledge base",
  schema: z.object({
    query: z.string().describe("The search query"),
    category: z.enum(["products", "shipping", "returns", "technical"]).optional(),
  }),
  execute: async ({ query, category }) => {
    return await searchKnowledgeBase(query, category);
  },
})
Each tool includes a Zod schema for type-safe parameters and an execute function.
5

Set Constraints

Define what the agent must and must not do:
.withConstraint("must", [
  "Always be polite and professional",
  "Search the knowledge base before providing policy information",
])
.withConstraint("must_not", [
  "Make promises about refunds without checking policies",
  "Share other customers' information",
])
Constraints ensure the agent follows company policies and best practices.
6

Add Guardrails and Tone

Enable safety guardrails and set the communication style:
.withGuardrails()
.withTone("Empathetic, professional, and solution-oriented")
Guardrails prevent harmful outputs, and tone ensures consistent communication.
7

Use with AI SDK

Export the configuration and use it with the Vercel AI SDK:
const { text } = await generateText({
  model: openai("gpt-4"),
  ...supportAgent.toAiSdk(), // Spreads { system, tools }
  prompt: "Customer inquiry here...",
});
The .toAiSdk() method converts the PromptSmith configuration to AI SDK format.

Expected Output

When you run this example, you’ll see output similar to:
Agent Response:
Thank you for contacting TechStore! I'd be happy to help you track your order.

I've looked up your order #12345, and I have good news! Your wireless headphones
have been shipped and are on their way to you. Here are the details:

- Order Status: Shipped
- Tracking Number: 1Z999AA10123456784
- Estimated Delivery: March 5, 2026

You can track your package using the tracking number above. Your order should
arrive within the estimated delivery window. Is there anything else I can help
you with today?

Key Concepts

Tool Integration - This example shows how to integrate real data sources (knowledge base, order database) into your agent using tools with Zod schemas for type safety.
Constraints - The must and must_not constraints ensure the agent follows company policies and maintains professional standards in all interactions.
Production Patterns - The combination of guardrails, clear capabilities, and strict constraints makes this agent production-ready and safe for customer interactions.

Customization Ideas

  • Add a create_ticket tool for escalating complex issues
  • Include a check_inventory tool for product availability
  • Add constraints for handling refunds and exchanges
  • Implement sentiment analysis to detect frustrated customers
  • Add a send_email tool for follow-up communications

Next Steps

Multi-Tool Agent

Learn how to build agents with multiple specialized tools

Tools Guide

Deep dive into creating and using tools effectively

Build docs developers (and LLMs) love