DEV Community

shashank ms
shashank ms

Posted on

Integrating LLM with Speech Recognition Models: A Step-by-Step Guide

We are going to build a local meeting minutes agent that transcribes audio recordings and extracts action items, decisions, and summaries in one pass. It is useful for teams who want to keep their voice data off third-party note-taking services and process everything through a single API. By running both speech recognition and inference on Oxlo.ai, you get flat per-request pricing that does not spike when you feed the model a long transcript. See https://oxlo.ai/pricing for current plan details.

What you'll need

  • Python 3.10 or newer
  • An Oxlo.ai API key from https://portal.oxlo.ai
  • The OpenAI SDK: pip install openai
  • A sample audio file in WAV or MP3 format

Step 1: Transcribe audio with Whisper

Oxlo.ai hosts Whisper Large v3 with no cold starts. We point the OpenAI SDK at the audio transcriptions endpoint and read the result as plain text.

from openai import OpenAI
import os

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key=os.getenv("OXLO_API_KEY"))

with open("meeting.wav", "rb") as audio_file:
    transcription = client.audio.transcriptions.create(
        model="whisper-large-v3",
        file=audio_file,
        response_format="text"
    )

print(transcription)

Step 2: Define the meeting analyst prompt

I keep the system prompt strict so the model returns the same Markdown sections every time. This makes the output predictable enough to pipe into other tools.

SYSTEM_PROMPT = """You are a meeting analyst. Read the transcript below and produce:

1. A one-paragraph summary.
2. A bullet list of key decisions.
3. A bullet list of action items with owners if mentioned.
4. A list of unresolved questions.

Use Markdown headers. Do not add fluff or emojis."""

Step 3: Generate structured minutes

I use kimi-k2.6 because its 131K context window handles long meetings without truncation. Since Oxlo.ai charges per request rather than per token, stuffing the entire transcript into the prompt does not change the price.

from openai import OpenAI
import os

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key=os.getenv("OXLO_API_KEY"))

transcript_text = transcription  # from Step 1

response = client.chat.completions.create(
    model="kimi-k2.6",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": transcript_text},
    ],
)

minutes = response.choices[0].message.content
print(minutes)

Step 4: Package the pipeline

This script ties the two stages together. It takes an audio path as an argument, transcribes it, and prints the finished minutes.

import argparse
import os
from openai import OpenAI

SYSTEM_PROMPT = """You are a meeting analyst. Read the transcript below and produce:

1. A one-paragraph summary.
2. A bullet list of key decisions.
3. A bullet list of action items with owners if mentioned.
4. A list of unresolved questions.

Use Markdown headers. Do not add fluff or emojis."""

def transcribe(audio_path: str, client: OpenAI) -> str:
    with open(audio_path, "rb") as f:
        result = client.audio.transcriptions.create(
            model="whisper-large-v3",
            file=f,
            response_format="text",
        )
    return result

def analyze(transcript: str, client: OpenAI) -> str:
    response = client.chat.completions.create(
        model="kimi-k2.6",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": transcript},
        ],
    )
    return response.choices[0].message.content

def main():
    parser = argparse.ArgumentParser(description="Generate meeting minutes from audio.")
    parser.add_argument("audio", help="Path to the audio file")
    args = parser.parse_args()

    client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key=os.getenv("OXLO_API_KEY"))

    print("Transcribing...")
    transcript = transcribe(args.audio, client)

    print("Analyzing...")
    minutes = analyze(transcript, client)

    print("\n=== MEETING MINUTES ===\n")
    print(minutes)

if __name__ == "__main__":
    main()

Run it

Save the script as meeting_agent.py, set your key, and point it at any recording.

export OXLO_API_KEY="YOUR_OXLO_API_KEY"
python meeting_agent.py ./standup.wav

Example output:

Transcribing...
Analyzing...

=== MEETING MINUTES ===

## Summary
The team reviewed Q3 migration blockers and agreed to delay the database cutover by one week.

## Key Decisions
- Postpone cutover to August 14 to allow extra load testing.
- Use DeepSeek V3.2 for the new code-review bot prototype.

## Action Items
- **Sarah**: Finalize the rollback playbook by August 10.
- **Mike**: Provision the staging cluster before Friday.

## Unresolved Questions
- Do we need a third-party audit for the new auth flow?

Wrap-up

This pipeline keeps all voice and text processing inside one provider. If you want to extend it, add speaker diarization with a local model like pyannote before sending the transcript to Oxlo.ai, or wrap the script in a FastAPI endpoint so other tools can POST audio files directly.

Top comments (0)