picoflow.io Docs

HomeInsuranceQuoteFlow tutorial

3. Prompt files and bounded collection

The model asks and explains. Typed tools validate the complete data record, and each stage sees only the state it needs to collect or revise.

Conversation quality comes from focused, reviewable prompt files; data integrity comes from schemas and tool handlers. HomeInsuranceQuoteFlow keeps those concerns separate so a friendly explanation cannot accidentally become a rating rule.

The goal

  • Compose a shared safety role with a stage-specific instruction file.
  • Inject only authoritative, relevant state into each stage prompt.
  • Validate a complete record in a tool handler before changing the cursor.
  • Keep calculated values out of collection prompts.

Prompt files are the readable specification

The shared role lives in prompt/role.md. It says this is a preliminary, non-binding estimate; forbids requests for Social Security numbers, payment cards, bank information, and birth dates; and forbids the model from calculating premiums, reason codes, option IDs, or validity dates.

Each stage has a second file: qualification.md, property.md, risk.md, coverage.md, review.md, present.md, contact.md, and referral.md. The TypeScript wrapper is intentionally small:

// prompt/home-insurance-prompt.ts
export class HomeInsurancePrompt {
  public static readonly Role = Prompt.file("role.md");
}

// qualification-step.ts
const Instructions = Prompt.file("prompt/qualification.md");

public getPrompt(): string {
  return `${HomeInsurancePrompt.Role}\n${Prompt.replace(Instructions, {
    CURRENT_DATE: homeInsuranceCurrentDate().toISOString().slice(0, 10),
    SUPPORTED_STATES: JSON.stringify(quoteConfig.supportedStates),
    QUALIFICATION: JSON.stringify(this.getState<Qualification>("qualification") ?? null),
    CORRECTION_REQUEST: JSON.stringify(this.getState("correctionRequest") ?? null),
  })}`;
}

Prompt.file(...) resolves relative to the source file, which keeps all of the flow’s text next to the steps it governs. Prompt.replace(...) is where the runtime data enters. It is injected afresh on each turn rather than trusted to survive in chat history.

State is context, not instruction

The qualification prompt receives a date, supported state list, its current qualification record, and an optional correction request. It does not receive the property or an old quote table. Likewise, CoverageStep receives only COVERAGE and CORRECTION_REQUEST:

public getPrompt(): string {
  return `${HomeInsurancePrompt.Role}\n${Prompt.replace(Instructions, {
    COVERAGE: JSON.stringify(this.getState<CoveragePreferences>("coverage") ?? null),
    CORRECTION_REQUEST: JSON.stringify(this.getState("correctionRequest") ?? null),
  })}`;
}

That small context window makes the model’s job obvious: fill or correct one record, then hand it to the one tool that accepts that record. It also means the review stage cannot accidentally rate an application while it is still being collected.

Tools validate before moving on

The tool schema helps the model produce structured arguments; the handler still validates them and applies business checks. QualificationStep is typical:

@Tool
protected async capture_home_qualification(args: unknown): Promise<ToolResponseType> {
  const parsed = QualificationSchema.safeParse(args);
  if (!parsed.success) {
    return stay("Collect a valid two-letter state, five-digit ZIP, purchase status, occupancy, and YYYY-MM-DD effective date.");
  }

  const effective = new Date(`${parsed.data.effectiveDate}T00:00:00.000Z`);
  if (Number.isNaN(effective.getTime()) || effective <= current || effective > latest) {
    return stay(`The effective date must be after ${today} and no more than one year later.`);
  }

  this.saveState({ qualification: durableJson(parsed.data) });
  return go(PropertyStep);
}

stay(...) retains the cursor and makes a concrete corrective instruction available for the next model response. A successful go(...) moves only after the state save has happened. The property and coverage steps apply the same pattern with their own Zod schemas.

The collection boundary

Stage The model may do Code must do
Qualification Ask for missing data and explain valid formats Validate date range and supported-state routing
Property Ask concise follow-ups and interpret a correction Validate profile fields and system years
Risk Collect claims, hazards, and protections Validate typed risk data
Coverage Explain the allowed choices Validate limits and save the selected deductible
Review Summarise persisted values and choose a correction tool Route back to the state owner

No collection prompt gets product factors or a formula. The state objects are validated inputs to the next stage; they are not an invitation for the model to invent a preliminary premium.

Next

4. Deterministic eligibility and rating follows those persisted records across the boundary into versioned product rules.