← Files SalesARCHIVED FILE

skills/find-customer-quotes/references/extraction-and-output.md

12.6 KB · Oct 4, 2026 · 12:02 UTC

↓ Download file

# Extraction And Output Rules

Use this reference after the skill has found or received transcript-like evidence. It owns the detailed quote extraction, speaker verification, ranking, output, and gap behavior for `find-customer-quotes`.

## Output format

Default: return a readable grouped summary (Markdown/plain text) that a human can scan quickly.

Use JSON only when:

- the user explicitly asks for JSON
- the results will be consumed downstream by another tool/workflow
- you need a machine-readable artifact for comparison/review

Readable summary should still preserve provenance and confidence, but in a compact format.

Minimum fields per quote:

- `theme`
- `quote` (verbatim)
- `speaker_name` (`"unknown"` if unavailable)
- `speaker_role_guess` (`customer`, `prospect`, `internal_seller`, `unknown`)
- `customer_confidence` (`0.0`-`1.0`)
- `theme_relevance` (`0.0`-`1.0`)
- `evidence` (brief reason the speaker is likely a customer and why the quote matches the theme)
  - `transcript_url` (the call or transcript link from the ~~Meeting Transcripts fetch response)

Strongly recommended extra fields when available:

- `call_date`
- `company`
- `call_title`
- `connector_file_id` (optional internal/debug field; useful for refetching with ~~Meeting Transcripts)
- `transcript_snippet` (short surrounding context, not a rewrite)

If a theme has insufficient high-confidence quotes, return fewer quotes and include a short gap note.

If no high-confidence customer/prospect quotes pass threshold but the reviewed transcript-like sources contain relevant internal, vendor-eval, partner-readiness, or implementation evidence, keep the customer quote count at zero and place those snippets only in a separate non-customer fallback section. Do not count fallback snippets toward the requested quote target or present them as customer/prospect language.

## Readable summary shape

Per theme, include:

- theme name
- number of quotes returned / target
- short one-line note on coverage quality, for example, `strong spread across 8 calls`
- quote list, each quote on its own bullet, with quote text, customer/company when available, speaker name when known, compact confidence, and a transcript link labeled `[Transcript]`

For readable summaries, do not print `speaker_role_guess` unless the user explicitly asks for role metadata or a quote needs an ambiguity caveat. Omit extra internal retrieval metadata unless the user asks.

Optional footer:

- `Gaps` section for themes with weak coverage
- `Internal / Non-Customer Evidence` section when no customer/prospect quotes pass threshold but relevant non-customer transcript evidence exists
- `Method notes` section if transcript formatting or speaker labeling quality reduced confidence

Fallback evidence section rules:

- Use a heading such as `Internal / Non-Customer Evidence`, never `Quote Candidates`.
- Include only verbatim snippets with strong theme relevance and enough surrounding context to explain why they are useful but excluded from the customer/prospect quote set.
- For each snippet, include speaker/context when known, `speaker_role_guess`, `customer_confidence`, `theme_relevance`, source link, and a usage note such as `Useful for an internal product brief; do not present as a customer quote`.
- Prefer a compact set of the strongest, most actionable snippets. Exclude garbled, bracket-reconstructed, or low-context fragments unless the uncertainty is essential and clearly noted.
- If high-confidence customer/prospect quotes exist, omit this fallback section unless the user explicitly asked for internal evidence too or the fallback materially explains a source gap.

## Candidate extraction

Run a theme-specific extraction pass over each transcript.

Goal:

- find verbatim quote candidates related to the theme
- identify whether the speaker is likely a customer/prospect
- preserve evidence and uncertainty

Important:

- Keep multiple quotes per call when they are distinct.
- Do not use a data structure keyed only by call id for quotes, because that collapses multiple valid quotes from the same call.
- Prefer a list of quote objects with a stable `quote_key`, such as `"{call_id}:{index}"` or `"{connector_file_id}:{index}"` when call id is unavailable.
- Candidate extraction may keep multiple quotes per call, but final exemplar selection should usually keep only one quote per call.

Include candidates that:

- directly express a pain point, blocker, constraint, concern, unmet need, or purchase condition
- are relevant to the theme
- are substantial enough to be useful, not generic praise
- appear to be spoken by an external participant or are ambiguous but promising

Exclude:

- obvious internal seller-side statements
- paraphrases that are not direct quotes unless the user explicitly asks for paraphrases
- concatenated or garbled fragments that combine multiple thoughts
- extremely short fragments with no clear meaning

## Speaker verification

Run a second pass over the extracted candidates with local transcript context.

For each candidate, provide:

- `speaker_role_guess`: `customer|prospect|internal_seller|unknown`
- `customer_confidence`: float `0-1`
- `evidence`: concise explanation grounded in transcript text/labels

Default threshold:

- Keep only `customer_confidence >= 0.8`
- Keep only `theme_relevance >= 0.75`

If fewer than `quotes_per_theme` remain, prefer returning fewer quotes over lowering `customer_confidence`. You may lower `theme_relevance` slightly, for example to `0.65`, if speaker evidence stays strong.

## Customer-likelihood heuristics

These heuristics improve precision. They are not substitutes for evidence.

Positive signals:

- Speaker labels or participant sections identify an external company contact.
- Quote uses customer-side operational constraints, such as procurement, legal, security review, compliance approval, budget ownership, or rollout blockers.
- Quote frames asks or needs from the seller, such as "we need", "we can't move forward without", "our team requires", or "this blocks procurement".
- Transcript context shows a seller asking a question and another speaker responding with the pain point.

Negative signals:

- Roadmap or launch language, such as "we shipped", "we can put that on the roadmap", or "our team is working on".
- Sales process language, such as pricing/packaging pitch, implementation promises, or next-step coordination without a customer pain point.
- Speaker labels indicate seller-side roles.

If no speaker labels and no clear contextual evidence exist, mark `speaker_role_guess="unknown"` and exclude from final exemplars unless the user explicitly asks for lower precision.

## Prompting pattern

Use two passes per theme.

Pass A: candidate extraction per transcript.

- Extract up to 2-4 verbatim quotes from this transcript relevant to the theme.
- Include quote text, tentative speaker role, theme relevance, and evidence.
- Favor recall, but exclude obvious internal quotes.

Pass B: cross-call verification and ranking per theme.

- Review all candidates for the theme.
- Re-check speaker classification using provided transcript context snippets.
- Deduplicate near-duplicates.
- Enforce call diversity, defaulting to one quote per call.
- Rank by customer confidence, theme relevance, specificity, and exemplar quality.
- Output top `quotes_per_theme` quotes, or fewer when evidence is weak.

When prompting, require verbatim quotes only, require an explicit `evidence` field, require abstention when uncertain, and instruct the model to prefer diversity across calls/customers when quality is similar.

## Deduplication and ranking

Apply deterministic filtering before final LLM ranking when possible:

- normalize whitespace and punctuation
- lowercase for comparison only
- drop exact duplicates
- drop quotes that are near-identical with trivial wording changes

Goal: maximize breadth of customer evidence, not just quote quality from a small number of calls.

Default final selection policy per theme:

- `1 quote per call` target
- `2 quotes per call` maximum
- use the second quote from the same call only if you cannot reach the requested `quotes_per_theme` with strong quotes from distinct calls, or if the second quote adds materially different evidence

When customer/account identity is available, also prefer breadth across customers:

- avoid stacking many quotes from the same customer unless coverage is sparse
- when two quotes are similar quality, choose the one that increases customer diversity

If you exceed one quote from a call, note it briefly in method notes.

Ranking priorities:

1. `customer_confidence`
2. `theme_relevance`
3. diversity across calls/customers
4. specificity/actionability of the pain point
5. clarity/readability while staying verbatim

Do not over-optimize for eloquence. A plain but specific customer blocker is better than a polished vague quote.

## Practical limits

Per theme defaults:

- search up to `20-40` calls
- fetch up to `10-20` transcripts initially
- extract up to `2-4` candidates per transcript
- verify/rank a pooled set of `20-50` candidates

If a theme is very broad:

- narrow search query before fetching more transcripts
- split into sub-themes only if the user asks

## Failure handling

Return structured gaps instead of failing the whole task.

Examples:

- no ~~Meeting Transcripts search results for theme
- search results exist but transcript fetch fails
- transcript content lacks enough speaker evidence
- enough relevant quotes found, but not enough high-confidence customer quotes

When gaps occur, include:

- `theme`
- `reason`
- `what was tried` (brief)
- `suggested next step`, such as widening the date range or lowering relevance threshold only

When the gap is `0` high-confidence customer/prospect quotes but relevant non-customer evidence exists, pair the gap with the fallback section above. Make the distinction explicit: `0/{target} customer/prospect quotes found; the evidence below is internal/vendor-eval/partner-readiness material and should not be used as customer quotes`.

## Suggested JSON shape

```json
{
  "results": [
    {
      "theme": "data residency",
      "quotes": [
        {
          "quote_key": "call-987654321:0",
          "quote": "We cannot roll this out until data stays in region for our EU users.",
          "speaker_name": "unknown",
          "speaker_role_guess": "customer",
          "customer_confidence": 0.93,
          "theme_relevance": 0.97,
          "evidence": "Quote describes the buyer's deployment blocker and references internal rollout constraints; no internal seller-side phrasing.",
          "transcript_url": "https://example.com/transcript/987654321"
        }
      ]
    }
  ],
  "gaps": [
    {
      "theme": "mobile application management",
      "reason": "Only 3 high-confidence customer quotes found",
      "what_was_tried": "Searched 32 calls, fetched 14 transcripts, lowered relevance threshold to 0.65 while keeping customer confidence >= 0.8",
      "suggested_next_step": "Widen date range or provide company/account segment filters"
    }
  ]
}
```

## Suggested readable shape

```md
Theme: api latency (10/10 quotes)
Coverage: Strong spread across 9 calls and 8 customers. 1 theme had repeated quotes from one call due to sparse alternatives.

- "..." - CustomerName (Speaker Name, customer_conf=0.99, relevance=0.98, [Transcript](https://example.com/transcript/123456789))
- "..." - CustomerName (Speaker Name, customer_conf=0.94, relevance=0.91, [Transcript](https://example.com/transcript/987654321))

Theme: deployment blockers (7/10 quotes)
Coverage: Good precision, lower volume.

- "..." - CustomerName (Speaker Name, customer_conf=0.99, relevance=1.00, [Transcript](https://example.com/transcript/555555555))

Gaps
- deployment blockers: Only 7 high-confidence customer/prospect quotes found after enforcing call diversity and confidence thresholds.

Theme: sales plugin setup friction (0/10 customer/prospect quotes)
Coverage: No high-confidence customer/prospect speakers found in the reviewed transcripts.

Gaps
- sales plugin setup friction: Reviewed transcript-like evidence, but speaker context was internal/vendor-eval rather than customer/prospect.

Internal / Non-Customer Evidence
- "The CRM needed reauthentication..." - Internal Speaker (speaker_role_guess=internal_seller, customer_conf=0.05, relevance=0.90, [Transcript](https://example.com/transcript/222222222)). Usage note: Useful for an internal product brief; do not present as a customer quote.
```

## Migration note

This skill intentionally improves on a common notebook pattern:

- Old pattern: join quotes to themes at the call level, then ask a model to filter.
- New pattern: retrieve transcripts per theme, extract quote candidates, then verify speaker role with evidence.

This produces better auditable exemplars and avoids collapsing multiple valid quotes from the same call.

SHA-256: adfa3f8cd5a5e7016d2415f026a7f6e3bb9fea0c01e0f4646d3c51ec9a983592