Production Deployment

Best practices for deploying compiled prompts to production.

Workflow Overview

  1. Compile prompts locally or in CI
  2. Save compiled JSON as artifacts
  3. Load compiled prompts in production
  4. Use CompiledProgram for inference

Save Compiled Prompts

scripts/compile.js
import { 
  defineSchema, ChainOfThought, BootstrapFewShot, 
  createProvider, exactMatch, z 
} from "@mzhub/promptc";
import { writeFileSync, readFileSync } from "fs";

// Load training data
const trainset = JSON.parse(
  readFileSync("data/trainset.json", "utf-8")
);

// Define schema and program
const schema = defineSchema({
  description: "Extract names from text",
  inputs: { text: z.string() },
  outputs: { names: z.array(z.string()) }
});

const provider = createProvider("openai");
const program = new ChainOfThought(schema, provider);

// Compile
const compiler = new BootstrapFewShot(exactMatch());
const result = await compiler.compile(program, trainset, {
  candidates: 20,
  concurrency: 5
});

// Save to prompts directory
writeFileSync(
  "prompts/name-extractor.json",
  JSON.stringify(result, null, 2)
);

console.log(`Compiled with score: ${result.meta.score}`);

Load in Production

src/services/extractor.js
import { 
  defineSchema, ChainOfThought, 
  loadCompiledProgram, createProvider, z 
} from "@mzhub/promptc";
import { readFileSync } from "fs";

// Same schema as compilation
const schema = defineSchema({
  description: "Extract names from text",
  inputs: { text: z.string() },
  outputs: { names: z.array(z.string()) }
});

// Production provider (can be different model)
const provider = createProvider("openai", {
  apiKey: process.env.OPENAI_API_KEY
});

// Base program
const program = new ChainOfThought(schema, provider);

// Load compiled config
const compiledJson = readFileSync("prompts/name-extractor.json", "utf-8");
const extractor = loadCompiledProgram(compiledJson, program);

// Export for use
export async function extractNames(text) {
  const result = await extractor.run({ text });
  return result.result.names;
}

Version Control

Track your compiled prompts in git for reproducibility:

prompts/
├── name-extractor.json    # v1.0
├── summarizer.json        # v1.2
└── classifier.json        # v2.1

# Commit with meaningful messages
git add prompts/name-extractor.json
git commit -m "feat(prompts): improve name extraction score to 0.95"
Prompt Versioning
Include version numbers in filenames or use a prompts manifest file to track which version is deployed.

CI/CD Integration

.github/workflows/compile.yml
name: Compile Prompts

on:
  push:
    paths:
      - 'data/trainset.json'
      - 'schemas/**'

jobs:
  compile:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Compile prompts
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: node scripts/compile.js
      
      - name: Commit compiled prompts
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"
          git add prompts/
          git commit -m "chore: update compiled prompts" || exit 0
          git push

Error Handling

import { withRetry } from "@mzhub/promptc";

async function extractNamesWithRetry(text) {
  return withRetry(
    () => extractor.run({ text }),
    {
      maxRetries: 3,
      initialDelayMs: 1000,
      retryOn: (error) => {
        // Retry on rate limits and timeouts
        return error.message.includes("rate") || 
               error.message.includes("timeout");
      }
    }
  );
}

Monitoring

async function runWithMonitoring(input) {
  const start = Date.now();
  
  try {
    const result = await extractor.run(input);
    
    // Log metrics
    console.log(JSON.stringify({
      event: "llm_call",
      latency_ms: Date.now() - start,
      input_tokens: result.trace.usage.inputTokens,
      output_tokens: result.trace.usage.outputTokens,
      success: true
    }));
    
    return result;
  } catch (error) {
    console.log(JSON.stringify({
      event: "llm_call",
      latency_ms: Date.now() - start,
      error: error.message,
      success: false
    }));
    throw error;
  }
}