audio-transcription
Audio transcription pipeline for RAG. Covers OpenAI Whisper (local via whisper.cpp, faster-whisper, Groq API), AssemblyAI (diarization, sentiment), Deepgram Nova-3 (real-time), timestamped chunking, speaker-aware chunking, multilingual (Whisper large-v3), and embedding transcripts for retrieval. USE WHEN: user mentions "transcribe audio", "Whisper", "whisper.cpp", "faster-whisper", "Groq Whisper", "AssemblyAI", "Deepgram", "speaker diarization", "podcast transcription", "meeting transcript", "multilingual audio" DO NOT USE FOR: video with visuals - use `video-rag`; live voice assistants (streaming to LLM) - not a RAG concern; audio that is actually a phone voicemail attachment in email - handle via `email-ingestion` then reuse this skill
What this skill does
# Audio Transcription for RAG
## Engine Comparison
| Engine | Deployment | Diarization | Real-Time | Cost | Best For |
|--------|------------|-------------|-----------|------|----------|
| whisper.cpp | Local (CPU/Metal) | No | No | Free | Low-volume offline |
| faster-whisper | Local (CUDA/CPU) | Via pyannote | No | Free | Self-hosted batch |
| Groq Whisper API | API | No | Near real-time | Cheap | Fast bulk transcription |
| OpenAI Whisper API | API | No | No | Medium | Simple drop-in |
| AssemblyAI | API | Yes | Yes | Medium | Meetings, podcasts |
| Deepgram Nova-3 | API | Yes | Yes (streaming) | Medium | Call centers, streaming |
## faster-whisper — Self-Hosted Batch
```python
from faster_whisper import WhisperModel
model = WhisperModel(
"large-v3",
device="cuda",
compute_type="float16", # or "int8_float16" on small GPUs
download_root="./models",
)
segments, info = model.transcribe(
"meeting.mp3",
language=None, # auto-detect; or "en", "it", ...
vad_filter=True,
vad_parameters={"min_silence_duration_ms": 500},
beam_size=5,
word_timestamps=True,
condition_on_previous_text=False,
)
print("detected:", info.language, "p=", info.language_probability)
transcript = []
for seg in segments:
transcript.append({
"start": seg.start,
"end": seg.end,
"text": seg.text.strip(),
"words": [{"w": w.word, "s": w.start, "e": w.end, "p": w.probability}
for w in (seg.words or [])],
})
```
## whisper.cpp — CPU / Apple Silicon
```bash
# Build
git clone https://github.com/ggerganov/whisper.cpp && cd whisper.cpp
make
./models/download-ggml-model.sh large-v3
# Transcribe
./main -m models/ggml-large-v3.bin -f input.wav -oj -of out
```
```python
# Python wrapper
from pywhispercpp.model import Model
m = Model("large-v3", n_threads=8)
for seg in m.transcribe("input.wav", language="auto", translate=False):
print(seg.t0, seg.t1, seg.text)
```
## Groq Whisper API
```python
import os
from groq import Groq
client = Groq(api_key=os.environ["GROQ_API_KEY"])
with open("podcast.mp3", "rb") as f:
result = client.audio.transcriptions.create(
model="whisper-large-v3",
file=("podcast.mp3", f.read()),
response_format="verbose_json",
timestamp_granularities=["segment", "word"],
language="en",
)
for seg in result.segments:
print(seg["start"], seg["end"], seg["text"])
```
## AssemblyAI — Diarization + Sentiment
```python
import assemblyai as aai
aai.settings.api_key = os.environ["ASSEMBLYAI_API_KEY"]
config = aai.TranscriptionConfig(
speaker_labels=True,
language_detection=True,
punctuate=True,
format_text=True,
sentiment_analysis=True,
auto_chapters=True,
entity_detection=True,
speech_model=aai.SpeechModel.best,
)
transcript = aai.Transcriber(config=config).transcribe("call.mp3")
for utt in transcript.utterances:
print(f"Speaker {utt.speaker} [{utt.start/1000:.1f}-{utt.end/1000:.1f}]: {utt.text}")
for chapter in transcript.chapters or []:
print(chapter.headline, chapter.summary)
```
## Deepgram Nova-3
```python
from deepgram import DeepgramClient, PrerecordedOptions, FileSource
dg = DeepgramClient(os.environ["DEEPGRAM_API_KEY"])
with open("call.wav", "rb") as f:
payload: FileSource = {"buffer": f.read()}
options = PrerecordedOptions(
model="nova-3",
smart_format=True,
diarize=True,
utterances=True,
paragraphs=True,
language="multi",
detect_language=True,
)
resp = dg.listen.rest.v("1").transcribe_file(payload, options)
for para in resp.results.channels[0].alternatives[0].paragraphs.paragraphs:
print(f"Speaker {para.speaker}:", para.sentences[0].text)
```
## Speaker Diarization with pyannote (Whisper + pyannote)
```python
from pyannote.audio import Pipeline
diar = Pipeline.from_pretrained(
"pyannote/speaker-diarization-3.1",
use_auth_token=os.environ["HF_TOKEN"],
)
diar_result = diar("meeting.wav")
# Merge Whisper word timestamps with diarization tracks
def assign_speakers(words: list[dict], diar_result) -> list[dict]:
out = []
for w in words:
mid = (w["s"] + w["e"]) / 2
speaker = "unknown"
for turn, _, spk in diar_result.itertracks(yield_label=True):
if turn.start <= mid <= turn.end:
speaker = spk
break
out.append({**w, "speaker": speaker})
return out
```
## Timestamped Chunking for RAG
```python
from dataclasses import dataclass
@dataclass
class AudioChunk:
text: str
start: float
end: float
speaker: str | None
source: str
language: str
def chunk_transcript(
segments: list[dict],
max_chars: int = 1000,
overlap_chars: int = 150,
source: str = "",
language: str = "en",
) -> list[AudioChunk]:
out: list[AudioChunk] = []
buf: list[dict] = []
buf_len = 0
current_speaker = None
for seg in segments:
speaker = seg.get("speaker")
# New chunk on speaker change OR size overflow
if (current_speaker and speaker and speaker != current_speaker) or \
(buf_len + len(seg["text"]) > max_chars and buf):
out.append(AudioChunk(
text=" ".join(s["text"] for s in buf).strip(),
start=buf[0]["start"],
end=buf[-1]["end"],
speaker=current_speaker,
source=source,
language=language,
))
# Rolling overlap: keep last few segments
keep = []
keep_len = 0
for s in reversed(buf):
keep_len += len(s["text"])
keep.insert(0, s)
if keep_len >= overlap_chars:
break
buf = keep
buf_len = sum(len(s["text"]) for s in buf)
buf.append(seg)
buf_len += len(seg["text"])
current_speaker = speaker or current_speaker
if buf:
out.append(AudioChunk(
text=" ".join(s["text"] for s in buf).strip(),
start=buf[0]["start"],
end=buf[-1]["end"],
speaker=current_speaker,
source=source,
language=language,
))
return out
```
## Multilingual with Whisper large-v3
```python
from faster_whisper import WhisperModel
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
# Transcribe in source language
segments, info = model.transcribe("italian_meeting.mp3", task="transcribe")
# Translate to English (Whisper built-in X->English)
segments_en, _ = model.transcribe("italian_meeting.mp3", task="translate")
# For non-English target, use a translator model on top
from transformers import pipeline
translator = pipeline("translation", model="Helsinki-NLP/opus-mt-it-es")
italian = " ".join(s.text for s in segments)
spanish = translator(italian, max_length=512)[0]["translation_text"]
```
## Embedding Transcripts
```python
from openai import OpenAI
oa = OpenAI()
def embed_chunks(chunks: list[AudioChunk]) -> list[dict]:
texts = [
(f"[{c.speaker}] {c.text}" if c.speaker else c.text)
for c in chunks
]
resp = oa.embeddings.create(model="text-embedding-3-large", input=texts)
return [{
"vector": d.embedding,
"metadata": {
"source": c.source,
"start": c.start,
"end": c.end,
"speaker": c.speaker,
"language": c.language,
"text": c.text,
},
} for c, d in zip(chunks, resp.data)]
```
## Full Pipeline
```python
def ingest_audio(path: str) -> list[dict]:
# 1. Transcribe with word timestamps
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
segments, info = model.transcribe(path, vad_filter=True, word_timestamps=True)
words = []
for seg in segments:
for w in (seg.words or []):
words.append({"s": w.start, "e": w.end, "text": w.word})
Related in Image & Video
watch
IncludedWatch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or Whisper API fallback), and hands the result to Claude so it can answer questions about what's in the video.
physical-ai-defect-image-generation
IncludedUse when the user wants to orchestrate defect image generation, run associated setup, or handle outputs on OSMO. The Day 0 path handles cold-start with USD-to-ROI, image-edit augmentation, and AnomalyGen to create initial PCBA datasets. The Day 1 path performs inference and labeling on real images. This skill helps with first-time asset setup, creation of finetuning checkpoints, and configuring deployment. Trigger keywords: defect image generation, dig workflow, dig pipeline, defect image detection workflow, aoi pipeline, aoi anomalygen, usd2roi anomalygen, day 0 pcba, day 1 pcba, day 1 real-photo alignment, day 1 manual roi, metal surface anomaly, glass defect, anomalygen finetune, setup_pcb, setup_metal, setup_glass, setup_pretrained, dig setup, dig datasets, dig pretrained checkpoint, dig image-edit endpoint.
accelint-react-best-practices
IncludedReact performance optimization and best practices. ALWAYS use this skill when working with any React code - writing components, hooks, JSX; refactoring; optimizing re-renders, memoization, state management; reviewing for performance; fixing hydration mismatches; debugging infinite re-renders, stale closures, input focus loss, animations restarting; preventing remounting; implementing transitions, lazy initialization, effect dependencies. Even simple React tasks benefit from these patterns. Covers React 19+ (useEffectEvent, Activity, ref props). Triggers - useEffect, useState, useMemo, useCallback, memo, inline components, nested components, components inside components, re-render, performance, hydration, SSR, Next.js, useDeferredValue, combined hooks.
elevenlabs-agents
IncludedBuild conversational AI voice agents with ElevenLabs Platform using React, JavaScript, React Native, or Swift SDKs. Configure agents, tools (client/server/MCP), RAG knowledge bases, multi-voice, and Scribe real-time STT. Use when: building voice chat interfaces, implementing AI phone agents with Twilio, configuring agent workflows or tools, adding RAG knowledge bases, testing with CLI "agents as code", or troubleshooting deprecated @11labs packages, Android audio cutoff, CSP violations, dynamic variables, or WebRTC config. Keywords: ElevenLabs Agents, ElevenLabs voice agents, AI voice agents, conversational AI, @elevenlabs/react, @elevenlabs/client, @elevenlabs/react-native, @elevenlabs/elevenlabs-js, @elevenlabs/agents-cli, elevenlabs SDK, voice AI, TTS, text-to-speech, ASR, speech recognition, turn-taking model, WebRTC voice, WebSocket voice, ElevenLabs conversation, agent system prompt, agent tools, agent knowledge base, RAG voice agents, multi-voice agents, pronunciation dictionary, voice speed control, elevenlabs scribe, @11labs deprecated, Android audio cutoff, CSP violation elevenlabs, dynamic variables elevenlabs, case-sensitive tool names, webhook authentication
humanizer
IncludedHumanize AI-generated text by detecting and removing patterns typical of LLM output. Rewrites text to sound natural, specific, and human. Uses 28 pattern detectors, 560+ AI vocabulary terms across 3 tiers, and statistical analysis (burstiness, type-token ratio, readability) for comprehensive detection. Use when asked to humanize text, de-AI writing, make content sound more natural/human, review writing for AI patterns, score text for AI detection, or improve AI-generated drafts. Covers content, language, style, communication, and filler categories.
generating-mermaid-diagrams
IncludedSalesforce architecture diagrams using Mermaid with ASCII fallback. Use this skill when generating text-based diagrams for Salesforce architecture, OAuth flows, ERDs, integration sequences, or Agentforce structure. TRIGGER when: user says "diagram", "visualize", "ERD", or asks for sequence diagrams, flowcharts, class diagrams, or architecture visualizations in Mermaid. DO NOT TRIGGER when: user wants PNG/SVG image output (use generating-visual-diagrams), or asks about non-Salesforce systems.