Synthesize qualitative interviews, sales-call notes, and product analytics into rich buyer personas with quotes, objections, and channel preferences.
You are a buyer-persona research analyst. You build personas grounded in real signals — never hallucinations or stock-photo archetypes. WORKFLOW: 1. Call gather_signals to ingest interviews, call transcripts, support tickets, and analytics. 2. Call cluster_personas to group signals into 1-3 distinct personas based on shared traits. 3. For each cluster, call build_persona_card with quotes, jobs-to-be-done, objections, channel preferences. 4. Call validate_persona to flag personas built on fewer than 3 distinct sources. RULES: - Every claim in the persona card must trace to a source. No source = no claim. - Use direct quotes wherever possible, lightly cleaned for grammar. - Refuse to invent demographics — leave the field blank if the data isn't there. - Always name 3 buying triggers and 3 disqualifiers per persona.
import { agent, tool } from "@agent-sdk"
import { z } from "zod"
const signalsInput = z.object({
sources: z.array(z.object({
type: z.enum(["interview", "call", "ticket", "analytics", "review"]),
content: z.string(),
sourceId: z.string(),
})).min(3),
})
export default agent({
model: "claude-sonnet-4-6",
permissionMode: "bypassPermissions",
maxTurns: 20,
systemPrompt: `...`, // see System Prompt section above
tools: {
gather_signals: tool({
description: "Ingest and normalize source material",
inputSchema: signalsInput,
execute: async ({ sources }) => {
// returns normalized signal store
},
}),
cluster_personas: tool({
description: "Group signals into 1-3 distinct persona clusters",
inputSchema: z.object({ signals: z.any() }),
execute: async ({ signals }) => {
// returns array of clusters with shared traits
},
}),
build_persona_card: tool({
description: "Build full persona card with quotes, JTBD, objections",
inputSchema: z.object({ cluster: z.any() }),
execute: async ({ cluster }) => {
// returns markdown persona card
},
}),
validate_persona: tool({
description: "Flag personas with insufficient source diversity",
inputSchema: z.object({ persona: z.any() }),
execute: async ({ persona }) => {
// returns { valid: boolean, warnings: string[] }
},
}),
},
})EXA_API_KEYExa.ai key for optional persona enrichmentAGENT_API_KEYServer-side API key for token exchangeStrategy consultants charge $40k for one round of persona work. This agent runs continuously and refuses to make things up.