Skip to content

The agentic flow

The questionnaire is not sent to the client as a link. ElevenLabs phones them, and a fleet of voice subagents conducts the intake over that call — one subagent introducing it, one per section, and two more to close it out.

Those subagents are all one ElevenLabs agent, Questionnaire Intake Agent, whose workflow contains a node per subagent. The workflow graph is what moves the call along; the client hears one interviewer throughout.

This page is the map. The subagents is the roster and the authoritative record of which markdown file each one loads; Context and handoff covers what travels between them; ElevenLabs setup is how it is actually configured in this repository.

The site is still the source of truth

No question text lives in an agent prompt. Every subagent is handed the section page from this site and asks what it finds there. Reword a question on its page and the next call asks the new wording — there is never a second copy of the questionnaire to keep in sync.

Why a fleet, and not one agent

A single agent could hold all eleven sections. On a voice call it does not work, for three reasons that compound:

Context is smaller than you think. The eleven section pages plus the protocol run to well over 60 KB of markdown. A voice agent is not just holding that — it is holding it alongside a growing transcript of a ninety-minute conversation. The section it is currently asking about competes for attention with ten it is not.

Latency is a hard budget. A phone call tolerates roughly a second of silence before it feels broken. Every token of prompt is time spent before the first token of speech. A prompt carrying all eleven sections makes every single question slower, including the trivial ones.

Attention degrades in the middle. A model reading one section page asks that section well. The same model reading eleven asks the first and last reliably and the ones in between approximately — it drifts into a neighbouring section's questions, or re-asks something answered forty minutes ago.

Splitting by section fixes all three at once, because a section is already the natural unit: it has its own page, its own field prefix, its own time estimate, and its own place in the order.

The split is the same one the site already makes

The subagent boundaries are not a new architecture imposed on the questionnaire. They are the section boundaries, which exist because the questionnaire was too long to be one page — for exactly the reason it is too long to be one agent.

The whole flow

flowchart TD
    COACH(["Coach queues an intake<br/>client record plus phone number"])
    CALL["Outbound call<br/>ElevenLabs to Twilio to the client"]
    INTRO["INTRO NODE<br/>who is calling and why<br/>consent to record, how long it takes"]
    BAIL(["Reschedule and end the call"])
    BREAK{{"Break offered<br/>same call, or a scheduled call back"}}
    S11["11 · Consent and sign-off<br/>~4 min · consent_*"]
    STOP["STOP AND REFER NODE<br/>say the stop wording verbatim<br/>do not soften, do not speculate"]
    HAND["HANDOVER NODE<br/>assemble record, list red flags and declines<br/>propose a triage outcome"]
    REVIEW(["Coach confirms the triage outcome"])
    MEAS(["9 · Measurements — in person, no agent"])

    subgraph SCREEN ["Screening — asked first so anything urgent surfaces early"]
        direction TB
        S1["1 · About you<br/>~5 min · client_*"]
        S2["2 · Health and medical history<br/>~15 min · health_*"]
        S3["3 · Systems review<br/>~12 min · sys_*"]
        S4["4 · Injuries and movement<br/>~2 min · inj_*"]
        S1 --> S2 --> S3 --> S4
    end

    subgraph BUILD ["Programme building — what the coach designs from"]
        direction TB
        S5["5 · Activity and training history<br/>~3 min · act_*"]
        S6["6 · Goals and motivation<br/>~3 min · goal_*"]
        S7["7 · Nutrition and hydration<br/>~15 min · nut_*"]
        S8["8 · Sleep, stress and recovery<br/>~7 min · life_*"]
        S10["10 · Preferences and logistics<br/>~7 min · pref_*"]
        S5 --> S6 --> S7 --> S8 --> S10
    end

    COACH --> CALL
    CALL --> INTRO
    INTRO -->|"not now"| BAIL
    INTRO -->|"ready to start"| S1
    S4 --> BREAK
    BREAK --> S5
    S10 --> S11
    S11 --> HAND

    INTRO -.->|"red flag"| STOP
    SCREEN -.->|"red flag"| STOP
    BUILD -.->|"red flag"| STOP
    STOP -.->|"de-escalated, resume"| SCREEN
    STOP --> HAND

    HAND --> REVIEW
    REVIEW --> MEAS

Read it as three movements. Screening first, so a stop condition surfaces in the first twenty minutes rather than the last. A break, because ninety minutes in one sitting is how you get abandoned calls. Consent last, once the client knows what they have actually agreed to.

The dotted lines are the escape hatch, and every node that asks a question has one — a red flag can be caught at any point in the call, not just during screening. The return arrow matters as much: if the trigger turns out not to qualify, control goes back to the section it came from and the call carries on. That is why an unsure subagent should take the escape rather than judge for itself — taking it is reversible, carrying on is not.

The cast

Subagent Workflow node Owns Ends by
Intro intro Identity check, what the call is, consent to record, expected length Moving to section 1, or rescheduling
Section 1–8, 10, 11 section_01section_11 One section each — its questions, in its order Offering a break, then moving to the next
Stop and refer stop_and_refer Everything after a red flag fires Moving to handover — or back, if de-escalated
Handover handover Assembling the record, the triage proposal, telling the client what happens next Ending the call

Thirteen subagents, and section 9 has none — measurements are taken by the coach in person at the baseline appointment. Nothing in it can be asked down a phone line.

With start_node and end_node, that is the fifteen-node workflow in the config.

What each one knows

A subagent loads its own section page plus a small, declared set of reference pages — never the whole reference directory. Sections with matrix questions get the matrix guidance; sections without it do not. Only the closing subagents carry the triage table.

The load map is the authoritative version of this, and the reference pages each declare their own audience in a banner at the top.

What this does not do

  • It does not decide anything. The fleet proposes a triage outcome; a human confirms it before the client trains. See the handover record.
  • It does not take measurements. Section 9 is in person.
  • It does not capture a signature. Section 11 records a verbal affirmation and flags that a written signature is outstanding.
  • It does not call back on its own. A stopped call resumes only when a coach says so.