🧠 BPO Brain

One pipeline: transcribe β†’ anonymize β†’ analyze β†’ aggregate β†’ generate the playbook β†’ test & approve.

πŸ‘€

What this does. Turns raw call recordings (audio pulled from Google Drive) into text transcripts with OpenAI Whisper. This is the first stage β€” every stage after it runs on this output.

  1. Confirm the Google Drive folder ID is filled in, then click πŸ”„ Load from Drive to list the recordings.
  2. Choose the Whisper model β€” use small to stay consistent with the rest of the corpus.
  3. Tick the files to process (or Select all / Select first N), then click β–Ά Start Transcription.
  4. Watch the Live Log. Each finished call is saved as one JSON in the transcripts/ folder.

Source

files done pending
πŸ“ in transcripts volume

Each call keeps exactly one transcript β€” re-running a done file overwrites it in place (no duplicate copies).

selected

No pending files. Load from Drive or upload audio.

tick to re-transcribe (you'll be asked to overwrite) selected

Nothing transcribed yet.

model Β· s

πŸ€– Ask about this transcript

Live log

Log output appears here during transcription…

What this does. Strips personally-identifiable information β€” names, phone numbers, emails, card numbers β€” from every transcript, so no customer data ever reaches the LLM. Required before Analyze.

  1. Reads transcripts/ (the Transcribe stage output) by default.
  2. Keep Redact person names (spaCy NER) checked β€” otherwise only phones get removed and names leak.
  3. Click Load Files, select the pending calls, then Start.
  4. Redacted copies land in anonymized/. Open one and confirm you see [NAME] / [PHONE] tokens.

Configuration

Reads transcripts/ (Transcribe β†’ Anonymize) and writes redacted copies into anonymized/. Override the source folder below if needed.

files done pending Β· redactions:
πŸ“ in anonymized volume

One anonymized JSON per call β€” re-running a done file overwrites it in place (no duplicate copies).

selected

No pending files. Click Load Files.

tick to re-anonymize (you'll be asked to overwrite) selected

Nothing anonymized yet.

Redactions:

Original

Anonymized

Live log

Log output appears here during anonymization…

What this does. Runs an LLM over each anonymized call to pull out structured insights β€” outcome, objections, effective phrases, failure points, QuickBooks errors, and a summary. Writes one analysis JSON per call.

  1. Leave Source = anonymized/ and Output = analyses/ β€” don't blank them (a blank field points at the whole project, and source must differ from output).
  2. Choose the LLM model and tick which fields to extract.
  3. Click Load Files, select calls, then Start.
  4. Each result is saved to analyses/; use the Review tab here to read individual ones.

Configuration

Extract these fields:

files done pending Β· outcomes:
πŸ“ in analyses volume

One analysis JSON per call β€” re-running a done file overwrites it in place (no duplicate copies).

selected

No pending files. Run Anonymize first, then Load.

tick to re-analyze (you'll be asked to overwrite) selected

Nothing analyzed yet.


      

Live log

Log output appears here during analysis…

What this does. Rolls every per-call analysis up into one cross-call picture β€” the most common objections, recurring QuickBooks errors, and the pitch beats and phrases that consistently work.

  1. Leave Source = analyses/ and Output = aggregate.json.
  2. Click Run Aggregation (analyze some calls first if it says none are available).
  3. Review the corpus stats and synthesized findings shown below β€” this is the input to Generate.

Re-running carries the previous aggregate's findings forward (objections / phrases / failure points accumulate, prior entries win) and backs up the old aggregate.json first.

Configuration

Rolls every per-call analysis into one corpus-wide aggregate: deterministic stats + a single LLM synthesis of objections β†’ rebuttals, winning phrases, and failure points. Feeds the playbook generation (M4-T9).

analyses available πŸ“ in aggregate volume

One LLM synthesis pass over the whole corpus β€” this is a single call (~30–90s), so there's no per-file progress to show.

An aggregate.json already exists β€” running again will ask before overwriting it.

πŸ“Š Corpus stats

Outcomes

Sentiments

Pitch beats

Top QB errors

🎯 Top objections β†’ best rebuttals

No objections synthesized.

✨ Winning phrases

⚠️ Common failure points

🧭 Flow recommendations

No aggregate yet. Run the Analyze stage on some calls, then Run Aggregation.

Live log

Log output appears here during aggregation…

What this does. Converts the aggregate into the production playbook β€” a master system prompt, a rebuttal library, and flow rules β€” the assets that replace the hand-written agent config.

  1. Confirm the Aggregate file (input) points at aggregate.json (run Aggregate first if it's missing).
  2. Tick which assets to generate.
  3. Click Generate Assets. Output is written to generated/assets.json β€” then go to Review.

Re-generating merges with the previous assets β€” your hand-edited rebuttals from Review are preserved (prior entries win; only genuinely-new ones are appended) and the old file is backed up first.

Configuration

Generate these assets:

Turns the cross-call aggregate into the production assets β€” master system prompt, rebuttal library, flow rules β€” that replace the hand-written system.yaml. Test them in the Review stage.

πŸ“ in generated volume

One LLM pass over the aggregate β€” a single call (~30–90s), so there's no per-item progress to show.

An assets.json already exists β€” generating again will ask before overwriting it. The previous version is backed up automatically.

πŸ“œ System prompt


        

🎯 Rebuttal library

🧭 Flow rules

No assets yet. Run the Aggregate stage, then Generate.

Live log

Log output appears here during generation…

What this does. Reads the anonymized call transcripts, pulls out every question the customer asked, clusters them, and checks whether the agent's playbook can actually answer each one β€” flagging the gaps (high-frequency questions we can't answer).

  • Reads anonymized/ (the Anonymize stage output).
  • Per-call question extraction is cached + resumable β€” re-run picks up where it left off.
  • Writes coverage_report.md + coverage.json to the coverage volume.

Three LLM passes over the corpus: extract customer questions per call β†’ cluster into canonical questions with counts β†’ classify each against the live playbook (covered / partial / gap).

transcripts available πŸ“ in coverage volume

Extracting per call (cached) β€” for a full 400+ corpus the first run takes a while; you can Stop and resume.

Log output appears here during the run…

πŸ“Š Coverage

πŸ“Œ Viewing an earlier run β€”
vs. previous run

πŸ•˜ Run history β€” are gaps closing?

Click a row to view that run's questions; ⬇ to download its report.

whencallsquestionsgapspartialcovered
#questioncategorysuggestion
No questions in this bucket.
Live agent Β· version Β· no live prompt yet β€” Publish to create one

πŸ“ž Place a test call

What the agent says to the customer when you advance each step of the LMI remote-session handshake (after the PIN). Leave a field blank to use the built-in wording. Saves live β€” used on the next call.

Step 4 (β€œSession live”) says nothing β€” clicking it just confirms the remote session connected and unlocks Pro Advisor transfer.

Just describe what went wrong on a call β€” like you'd tell a colleague. The Brain figures out which part of the script to change, shows you the exact edit, and applies it on your OK. Live on the next call, no engineer, no redeploy.

Relevant transcript (optional β€” helps accuracy)
import from a past call: or
(use a strong model β€” Claude/Kimi β€” for this, not the latency default)

Probe the agent: type customer lines and see how it replies. Use πŸ›  Feedback to turn a bad reply into a concrete Call Sections edit.

πŸ§ͺ See how the agent would reply

Type customer lines; the LLM responds as Sarah using the real agent prompt. Keep going to replay a multi-turn call (e.g. reproduce a bad one).

Test against:

Latest reply:

Not what you wanted? Describe the fix in πŸ›  Feedback and apply it to the relevant Call Section.

Write the answer in rough form β€” the Brain rewrites it into polished, conversational phrasing. Approve as-is, tweak, ask for another pass, or add to the library.

Polished reply (edit if you like):

πŸ“‹ Call playbooks

One vetted script per issue type. The agent loads the one matching a call's issue (and can switch mid-call). Goes live on the next call β€” no deploy.

Playbooks

  • No playbooks yet β€” click + New.
Select a playbook or create a new one.
Unsaved changes

🧩 Call sections (phased KB)

At call start the agent loads the Core (Section 1), the always-on Behavior Rules (10) and the early phases (Opening, Reaching the owner, Trust). The later walkthrough phases load on demand as the call reaches them. Each section has an Instruction, optional FAQ blocks, and an optional Steps block β€” all saved together when you press Save, live on the next call.

Shortcodes you can use in any section (filled per call from the form/CSV, else the default in the Variables / Shortcodes section): {agent} Β· {customer} Β· {company} Β· {issue} Β· {ticket}.

Sections

  • Loading…
Select a phase to edit.

Section 1 is the always-on Core (loaded on every call). Use {agent} where the agent's name should go.

This is the exact first line the customer hears β€” spoken word-for-word. Keep it to one natural sentence; use {agent} for the agent's name.

Always-on Behavior Rules β€” injected on every call and win over the script on conflict. Not a phase (never in the call's step order). Use {agent} for the name.

Not spoken β€” this defines the {shortcode} defaults. One name = default value per line (e.g. agent = Peter); # lines are ignored. The per-call form/CSV value wins; the default here is used when a call doesn't supply one. ⚠️ Keep ticket generic text β€” never a fake case number.

FAQ β€” optional Β· the agent answers these if the customer asks

No FAQs yet. Add common questions for this phase β€” each is its own block.

Step-by-step β€” optional Β· one use case, given one step per turn

No steps yet. Add the ordered steps for this use case.

Unsaved changes

πŸ›‘οΈ Guardrails β€” forbidden phrases

A deny-list of phrases the agent must never say (e.g. claiming to work for Intuit, promising a guaranteed refund). Matched on each spoken sentence β€” on a hit the agent speaks the replacement instead, or the whole sentence is dropped if you leave the replacement blank. Edits are live on the next call (within ~30s). Matching is case-insensitive.

Guardrails ship in observe-mode by default (CC_GUARDRAIL_FLAG_ONLY=true) β€” hits are logged to the call Inspector but the audio is not altered. An engineer flips CC_GUARDRAIL_FLAG_ONLY=false on qb-api to start enforcing.

Phrase Replacement Active

of the selected already have output in the volume. Overwrite them, or skip and process only the new ones?

already exists in the volume. Overwrite it?