Skip to content

RFC: Deep module — AI Prompt Service (structured prompts + Zod validation) #5

@Khoa-Dam

Description

@Khoa-Dam

Problem

ai.service.ts has inline prompt strings, raw JSON.parse on LLM output (crashes on malformed responses), and hardcoded model/token config. No few-shot examples to guide output format.

Proposed Interface

// src/ai/prompts/templates.ts

interface PromptConfig {
  systemPrompt: string;
  fewShot: Anthropic.MessageParam[];   // pre-built examples
  assistantPrefill: string;            // CoT trigger
  temperature: number;
  maxTokens: number;
}

const parseReportConfig: PromptConfig;    // 3 few-shot examples
const analyzeAreaConfig: PromptConfig;    // CoT prefill: "Let me analyze..."
// src/ai/prompts/schemas.ts

export const ParsedReportSchema = z.object({
  crime_type: z.nativeEnum(CrimeType),
  severity_level: z.number().min(1).max(3),
  description: z.string(),
});

export const AreaAnalysisSchema = z.object({
  risk_level: z.enum(['low', 'medium', 'high']),
  summary: z.string(),
  recommendations: z.array(z.string()),
});

export function extractJson(raw: string): string; // strips ```json fences + CoT preamble

What it hides:

  • Few-shot example construction
  • Chain-of-thought prefill for analyzeArea
  • Markdown fence stripping before JSON.parse
  • Zod schema validation with typed error messages
  • Model name and token limits from env via ConfigService

Implementation

  1. Create src/ai/prompts/ directory with templates.ts and schemas.ts
  2. Add Zod (npm i zod) if not already installed
  3. Replace JSON.parse(content) calls with ParsedReportSchema.parse(extractJson(content))
  4. Add 3 few-shot examples to parseReportConfig
  5. Add CoT prefill to analyzeAreaConfig

Trade-offs

  • ✅ Zod parse throws typed errors → proper 422 response instead of 500 crash
  • ✅ Few-shot examples reliably guide LLM output format
  • ✅ Model config moved to env → no redeploy to switch models
  • ⚠️ Zod adds ~15kB to API bundle (negligible for NestJS)
  • ⚠️ Few-shot examples add ~300 tokens per request → marginal cost increase

Files affected

  • src/ai/ai.service.ts
  • src/ai/prompts/templates.ts (new)
  • src/ai/prompts/schemas.ts (new)
  • src/ai/ai.module.ts

🤖 Generated with Claude Code via /improve-codebase-architecture + /prompt-engineer

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions