> ## Documentation Index
> Fetch the complete documentation index at: https://docs.poly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Tutorial: Global ASR

> PolyAcademy Level 2 – Improve speech recognition accuracy with keyphrase boosting and transcript corrections.

export const LessonMeta = ({level, difficulty, time}) => {
  const levelConfig = {
    1: {
      badge: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
      label: 'Level 1'
    },
    2: {
      badge: 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200',
      label: 'Level 2'
    },
    3: {
      badge: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
      label: 'Level 3'
    }
  };
  const difficultyConfig = {
    Beginner: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
    Intermediate: 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200',
    Advanced: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'
  };
  const lvl = levelConfig[level] || levelConfig[1];
  const diffColor = difficultyConfig[difficulty] || difficultyConfig['Beginner'];
  return <div className="flex flex-wrap items-center gap-2 my-4 not-prose">
      <span className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold ${lvl.badge}`}>
        {lvl.label}
      </span>
      <span className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold ${diffColor}`}>
        {difficulty}
      </span>
      {time && <span className="inline-flex items-center gap-1 text-xs text-gray-500 dark:text-gray-400">
          <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          {time}
        </span>}
    </div>;
};

export const Quiz = ({questions = []}) => {
  const [selected, setSelected] = useState({});
  const [resetCount, setResetCount] = useState(0);
  const letters = ['A', 'B', 'C', 'D'];
  const handleSelect = (qIdx, optIdx) => {
    if (selected[qIdx] !== undefined) return;
    setSelected(prev => ({
      ...prev,
      [qIdx]: optIdx
    }));
  };
  const handleReset = () => {
    setSelected({});
    setResetCount(c => c + 1);
  };
  if (!questions?.length) return null;
  const getOptionClasses = ({hasAnswered, isThisCorrect, isThisSelected}) => {
    if (!hasAnswered) {
      return {
        btn: 'flex w-full items-center gap-3 py-2.5 px-4 rounded-xl text-sm leading-normal transition-all duration-150 text-left border cursor-pointer border-gray-200 bg-white text-gray-700 hover:border-gray-300 hover:bg-gray-50 hover:shadow-sm dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:border-gray-500 dark:hover:bg-gray-700',
        badge: 'w-6 h-6 rounded-full text-xs font-bold flex items-center justify-center shrink-0 leading-none transition-all duration-150 bg-gray-100 text-gray-500 dark:bg-gray-700 dark:text-gray-300',
        icon: null
      };
    }
    if (isThisCorrect) {
      return {
        btn: 'flex w-full items-center gap-3 py-2.5 px-4 rounded-xl text-sm leading-normal transition-all duration-150 text-left border cursor-default border-green-400 bg-green-50 text-green-900 font-medium dark:border-green-500 dark:bg-green-950 dark:text-green-100',
        badge: 'w-6 h-6 rounded-full text-xs font-bold flex items-center justify-center shrink-0 leading-none transition-all duration-150 bg-green-500 text-white dark:bg-green-500',
        icon: <svg className="shrink-0 w-4 h-4 text-green-500 dark:text-green-400 ml-auto" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
          </svg>
      };
    }
    if (isThisSelected) {
      return {
        btn: 'flex w-full items-center gap-3 py-2.5 px-4 rounded-xl text-sm leading-normal transition-all duration-150 text-left border cursor-default border-red-400 bg-red-50 text-red-900 dark:border-red-500 dark:bg-red-950 dark:text-red-100',
        badge: 'w-6 h-6 rounded-full text-xs font-bold flex items-center justify-center shrink-0 leading-none transition-all duration-150 bg-red-500 text-white dark:bg-red-500',
        icon: <svg className="shrink-0 w-4 h-4 text-red-400 dark:text-red-400 ml-auto" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
          </svg>
      };
    }
    return {
      btn: 'flex w-full items-center gap-3 py-2.5 px-4 rounded-xl text-sm leading-normal transition-all duration-150 text-left border cursor-default border-gray-100 bg-white text-gray-400 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-500',
      badge: 'w-6 h-6 rounded-full text-xs font-bold flex items-center justify-center shrink-0 leading-none transition-all duration-150 bg-gray-100 text-gray-500 dark:bg-gray-700 dark:text-gray-500',
      icon: null
    };
  };
  return <div key={resetCount} className="my-6">
      {questions.map((q, qIdx) => {
    const answer = selected[qIdx];
    const hasAnswered = answer !== undefined;
    const isCorrect = answer === q.correct;
    return <div key={String(qIdx)} className="mb-8">
            <p className="flex items-start gap-2.5 font-semibold text-sm mb-3 mt-0 leading-relaxed text-gray-900 dark:text-gray-100">
              <span className="inline-flex items-center justify-center w-5 h-5 rounded-full bg-gray-800 dark:bg-gray-200 text-white dark:text-gray-900 text-xs font-bold shrink-0 mt-px leading-none">
                {qIdx + 1}
              </span>
              {q.q}
            </p>

            <div className="flex flex-col gap-2">
              {q.options.map((opt, i) => {
      const isThisCorrect = i === q.correct;
      const isThisSelected = i === answer;
      const {btn, badge, icon} = getOptionClasses({
        hasAnswered,
        isThisCorrect,
        isThisSelected
      });
      return <button key={String(i)} type="button" onClick={() => handleSelect(qIdx, i)} className={btn}>
                    <span className={badge}>{letters[i]}</span>
                    <span className="flex-1">{opt}</span>
                    {icon}
                  </button>;
    })}
            </div>

            {hasAnswered ? <div className={`mt-3 py-3 pl-4 pr-3.5 rounded-r-xl text-sm leading-relaxed border-l-4 ${isCorrect ? 'border-green-500 bg-green-50 dark:bg-green-950 dark:border-green-500' : 'border-red-500 bg-red-50 dark:bg-red-950 dark:border-red-500'}`}>
                <span className={`font-semibold ${isCorrect ? '!text-green-800 dark:!text-green-200' : '!text-red-800 dark:!text-red-200'}`}>
                  {isCorrect ? 'Correct.' : 'Not quite.'}
                </span>{' '}
                <span className="!text-gray-700 dark:!text-gray-300">{q.explanation}</span>
              </div> : null}
          </div>;
  })}

      <button type="button" onClick={handleReset} className="mt-1 text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 underline underline-offset-2 cursor-pointer transition-colors duration-150">
        Reset quiz
      </button>
    </div>;
};

export const ProgressTracker = ({lessonNum, totalLessons, level}) => {
  const [checked, setChecked] = useState(false);
  return <div onClick={() => setChecked(prev => !prev)} className={checked ? 'flex items-center gap-3 p-4 rounded-lg border-2 border-green-600 bg-green-50 dark:bg-green-950 cursor-pointer select-none transition-all' : 'flex items-center gap-3 p-4 rounded-lg border-2 border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 cursor-pointer select-none transition-all'}>
      <div className={checked ? 'w-5 h-5 rounded border-2 border-green-600 bg-green-600 flex items-center justify-center shrink-0 transition-all' : 'w-5 h-5 rounded border-2 border-gray-400 dark:border-gray-500 bg-white dark:bg-gray-800 flex items-center justify-center shrink-0 transition-all'}>
        {checked ? <svg width="10" height="8" viewBox="0 0 10 8" fill="none">
            <path d="M1 4L3.5 6.5L9 1" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
          </svg> : null}
      </div>
      <div>
        <div className={checked ? 'font-semibold text-sm text-green-700 dark:text-green-300' : 'font-semibold text-sm text-gray-700 dark:text-gray-200'}>
          {checked ? 'Lesson complete' : 'Mark lesson complete'}
        </div>
        {lessonNum && totalLessons ? <div className="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
            {level ? level + ' - ' : ''}Lesson {lessonNum} of {totalLessons}
          </div> : null}
      </div>
    </div>;
};

<Info>
  **Level 2 – Lesson 6 of 8** – Configure speech recognition to reduce misrecognition and improve routing.
</Info>

<LessonMeta level={2} difficulty="Intermediate" time="20 min" />

[ASR](/voice-channel/advanced/call-settings#keyphrases) determines what the agent *hears*. Every downstream system depends on it: retrieval, routing, response control, handoff logic. Small transcription errors here silently break otherwise well-designed agents. Global ASR is where you correct systematic listening problems at the source.

## What global ASR is for

<CardGroup cols={2}>
  <Card title="Reduce clarifications" icon="comment-question">
    Minimize unnecessary clarification questions
  </Card>

  <Card title="Improve routing" icon="route">
    Increase routing accuracy for calls
  </Card>

  <Card title="Stabilize retrieval" icon="database">
    Improve Knowledge topic selection for spoken queries
  </Card>

  <Card title="Fix transcription" icon="spell-check">
    Correct recurring transcription errors at the source
  </Card>
</CardGroup>

Global ASR is not a substitute for good KB design or clear agent behavior rules. It improves transcription accuracy – it does not add new knowledge to the agent.

## Which tool to use

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
flowchart TD
    A[ASR problem identified] --> B{What type of error?}
    B -->|Word is correct but under-recognized| C[Keyphrase Boosting]
    B -->|ASR consistently hears the wrong thing| D[Transcript Corrections]
    C --> E[Add keyphrase → start with Default bias strength]
    D --> F[Add correction → define misheard expression and replacement]
    E --> G[Test in Call → increase bias only if errors persist]
    F --> G
    G --> H{Improvement confirmed?}
    H -->|Yes| I[Promote carefully]
    H -->|No| B
```

## Two essential tools

<Tabs>
  <Tab title="Keyphrase Boosting">
    Keyphrase Boosting biases the ASR model toward recognizing specific words or phrases more reliably.

    ### When to use it

    <AccordionGroup>
      <Accordion title="Use cases" icon="lightbulb">
        * A word is important for routing or actions
        * Misrecognition causes the agent to take the wrong path
        * Users consistently repeat themselves for the same term
      </Accordion>

      <Accordion title="Typical candidates" icon="list">
        **Department names:**

        * "front desk"
        * "billing"
        * "room reservations"

        **Product or service names:**

        * "bell desk"
        * "late checkout"

        **Action-critical verbs:**

        * "cancel"
        * "confirm"
      </Accordion>
    </AccordionGroup>

    ### How to configure

    <Steps>
      <Step title="Add the keyphrase">
        Enter it exactly as you want it recognized
      </Step>

      <Step title="Set bias strength">
        Start with Default bias strength
      </Step>

      <Step title="Adjust if needed">
        Increase toward Maximum only if errors persist
      </Step>
    </Steps>

    <Warning>
      **Important guidance:**

      * Bias strength is cumulative. Over-biasing many terms can degrade overall accuracy
      * Avoid boosting generic words like "room" unless they are routing-critical
      * Prefer multi-word phrases over single words when possible
      * **Example:** If callers asking for the "bell desk" are frequently routed incorrectly, boost "bell desk" rather than boosting "desk"
    </Warning>
  </Tab>

  <Tab title="Transcript Corrections">
    Transcript Corrections rewrite text after transcription, mapping common errors to the intended phrase.

    ### When to use it

    <AccordionGroup>
      <Accordion title="Use cases" icon="lightbulb">
        * ASR consistently hears the same wrong thing
        * Accents or homophones cause predictable errors
        * Brand or proper names are repeatedly mangled
      </Accordion>

      <Accordion title="Typical examples" icon="list">
        **Homophones:**

        * "copper" → "hopper"

        **Accent-driven substitutions:**

        * "reef fund" → "refund"

        **Brand names:**

        * "Hopper Consumer" → "Hopper"
      </Accordion>
    </AccordionGroup>

    ### How to configure

    <Steps>
      <Step title="Choose match type">
        Select substring or regex
      </Step>

      <Step title="Define misheard expression">
        Enter what ASR incorrectly transcribes
      </Step>

      <Step title="Define correction">
        Enter the intended replacement text
      </Step>
    </Steps>

    <Warning>
      **Important guidance:**

      * Prefer narrow matches over broad regex
      * Avoid corrections that could unintentionally rewrite unrelated phrases
      * If unsure, test in Sandbox with real call audio before promoting
      * **Example:** If "cancel" is sometimes transcribed as "council," add a correction rather than increasing bias on "cancel" alone
    </Warning>
  </Tab>
</Tabs>

## Check your understanding

<Quiz
  questions={[
{
q: "A caller says 'I need to cancel my booking' but the agent hears 'I need to council my booking' and routes to the wrong topic. Should you use Keyphrase Boosting or Transcript Corrections?",
options: [
  "Keyphrase Boosting – increase bias on 'cancel'",
  "Transcript Corrections – map 'council' to 'cancel'",
  "Both – boost 'cancel' and correct 'council' simultaneously",
  "Neither – this is a Managed Topic naming issue",
],
correct: 1,
explanation: "ASR is consistently mishearing 'cancel' as 'council' – this is a predictable substitution error. Transcript Corrections rewrite after transcription and are the right tool for this pattern.",
}
]}
/>

## A practical workflow

<Steps>
  <Step title="Review recent calls">
    Look for calls where:

    * The agent asked for repetition
    * The wrong KB topic was selected
    * Routing or handoff failed unexpectedly
  </Step>

  <Step title="Identify the problem">
    Find the specific word or phrase that failed
  </Step>

  <Step title="Choose your tool">
    Decide:

    * **Boost** if the word is correct but under-recognized
    * **Correct** if the word is consistently misheard as something else
  </Step>

  <Step title="Apply minimal change">
    Make the smallest possible adjustment
  </Step>

  <Step title="Test in Call">
    Verify the improvement
  </Step>

  <Step title="Promote carefully">
    Only promote after confirming improvement
  </Step>
</Steps>

## Common mistakes

<Warning>
  **Avoid these pitfalls:**

  * Boosting everything "just in case"
  * Using Transcript Corrections to fix KB design problems
  * Applying maximum bias globally without testing
  * Forgetting that local (flow-level) ASR settings override global ones
</Warning>

## Check your understanding

<Quiz
  questions={[
{
q: "When should you use Transcript Corrections instead of Keyphrase Boosting?",
options: [
  "When a word is under-recognized but correctly transcribed",
  "When ASR consistently mishears one specific thing as another",
  "When overall transcription quality is low across all words",
  "When you need multi-language support",
],
correct: 1,
explanation: "Keyphrase Boosting improves recognition of words that are correct but under-weighted. Transcript Corrections rewrite after transcription – for consistent mishear patterns like \"refund\" being transcribed as \"reef fund\".",
}
]}
/>

## Verification checklist

<Check>
  Verification is complete when:

  * Previously misheard phrases are transcribed correctly
  * The agent asks fewer clarification questions for known terms
  * Routing and KB selection stabilise in live call testing
  * Behavior remains consistent after promotion between environments

  Global ASR tuning is iterative. Small, deliberate adjustments here pay off more than large rewrites elsewhere.
</Check>

## Try it yourself

<Steps>
  <Step title="Challenge: Diagnose and configure an ASR fix">
    A caller says "I'd like a refund" but ASR consistently transcribes it as "I'd like a reef fund". The `refund_request` topic therefore never triggers.

    Answer:

    1. Should you use Keyphrase Boosting or Transcript Corrections – and why?
    2. Write the full configuration.

    <Accordion title="Hint">
      Ask yourself: is ASR hearing the right word but recognizing it poorly, or is it consistently mishearing one thing as another?
    </Accordion>

    <Accordion title="Example solution">
      1. **Transcript Corrections** – because ASR is consistently mishearing "refund" as "reef fund". This is a predictable substitution error, not an under-recognition problem.

      2. **Configuration:**
         * **Match type:** Substring
         * **Misheard expression:** `reef fund`
         * **Correction:** `refund`
    </Accordion>
  </Step>
</Steps>

## Check your understanding

<Quiz
  questions={[
{
q: "What is the main risk of boosting too many keyphrases?",
options: [
  "Keyphrases stop working after 30 days",
  "Bias strength is cumulative and can degrade overall ASR accuracy",
  "It causes noticeable latency spikes",
  "Boosted words are excluded from Transcript Corrections",
],
correct: 1,
explanation: "Bias strength is cumulative – boosting too many terms can degrade overall ASR accuracy. Always start with Default bias and increase only if errors persist.",
}
]}
/>

<CardGroup cols={2}>
  <Card title="← Previous: Audio management" icon="arrow-left" href="/learn/guides/advanced/audio-management">
    Lesson 5 of 8
  </Card>

  <Card title="Next: Variants →" icon="arrow-right" href="/learn/guides/advanced/variants">
    Lesson 7 of 8
  </Card>
</CardGroup>

<ProgressTracker lessonKey="l2-6-global-asr" lessonNum={6} totalLessons={8} level="Level 2" />
