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
- Create
src/ai/prompts/ directory with templates.ts and schemas.ts
- Add Zod (
npm i zod) if not already installed
- Replace
JSON.parse(content) calls with ParsedReportSchema.parse(extractJson(content))
- Add 3 few-shot examples to
parseReportConfig
- 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
Problem
ai.service.tshas inline prompt strings, rawJSON.parseon LLM output (crashes on malformed responses), and hardcoded model/token config. No few-shot examples to guide output format.Proposed Interface
What it hides:
analyzeAreaJSON.parseConfigServiceImplementation
src/ai/prompts/directory withtemplates.tsandschemas.tsnpm i zod) if not already installedJSON.parse(content)calls withParsedReportSchema.parse(extractJson(content))parseReportConfiganalyzeAreaConfigTrade-offs
Files affected
src/ai/ai.service.tssrc/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