Multi-speaker Podcast Generation with Open-Notebook: Implementation Guide
Open-Notebook implements a fully-featured, multi-speaker podcast generation pipeline that stitches together domain models, asynchronous job queues, and REST API services.
The lfnovo/open-notebook repository provides a production-ready architecture for generating conversational audio content with multiple speakers. The system combines persistent entity definitions in the domain layer with crash-resilient execution via the surreal-commands framework to handle complex podcast synthesis workflows.
Domain Models for Multi-Speaker Podcasts
The domain layer in open_notebook/podcasts/models.py defines three core entities that encapsulate podcast configuration, speaker definitions, and episode state.
EpisodeProfile Configuration
The EpisodeProfile class manages high-level parameters for episode generation. It specifies which language models handle distinct phases of the creation process and defines structural constraints.
Key fields include:
outline_llm: Model identifier for generating the conversation structuretranscript_llm: Model identifier for creating dialogue contentspeaker_config: Reference to voice and personality definitionsdefault_briefing: Context provided to all episodes using this profilenum_segments: Target number of conversational segments to generate
SpeakerProfile Definition
The SpeakerProfile class stores voice synthesis and personality data for 1-4 speakers. It integrates with TTS providers through the voice_model field while maintaining individual speaker characteristics.
Each speaker dictionary contains:
name: Display identifier for the participantvoice_id: TTS provider-specific voice referencebackstory: Character history informing dialogue contextpersonality: Behavioral traits affecting speech patterns
PodcastEpisode Storage
The PodcastEpisode model persists generated content and tracks execution state. It maintains a reference to the surreal-commands job via the command field, enabling asynchronous status monitoring and crash recovery.
Stored content includes:
briefing: Input context provided for the episodeoutline: Structured conversation flow generated by the outline LLMtranscript: Generated dialogue text from the transcript LLMaudio_file: Path to the final synthesized audio filecontent: Processed episode metadata and references
Asynchronous Job Execution
The system uses surreal-commands for crash-resilient, asynchronous processing of long-running podcast generation tasks.
The generate_podcast Command
Located in commands/podcast_commands.py, the generate_podcast command encapsulates the complete generation workflow. It orchestrates the transition from outline to audio while maintaining persistent state.
This command coordinates:
- Outline generation using the configured
outline_llm - Multi-speaker dialogue creation via
transcript_llm - Audio synthesis across multiple voice models defined in
SpeakerProfile - Progress persistence through the
PodcastEpisode.commandreference
Crash-Resilient Processing
By delegating execution to the surreal-commands queue, the system ensures that podcast generation survives process restarts. The PodcastEpisode.command field links the domain entity to the job queue state, allowing clients to poll for completion status and enabling automatic retry of failed operations.
API Service Layer
The PodcastService class in api/podcast_service.py provides the HTTP façade for client interactions with the podcast generation system.
This service exposes endpoints for:
- Triggering new
generate_podcastjobs with validated configuration - Verifying
EpisodeProfileandSpeakerProfileschema compliance - Polling generation status via the surreal-commands integration
- Retrieving completed episodes with
audio_fileURLs and metadata
Model Registry Integration
Both EpisodeProfile and SpeakerProfile expose configuration resolution methods that delegate to the centralized model registry at open_notebook.ai.models.Model.
Configuration Resolution Methods
The domain models implement three helper methods for dynamic provider configuration:
resolve_outline_config(): Returns LLM parameters for outline generationresolve_transcript_config(): Returns LLM parameters for dialogue generationresolve_tts_config(): Returns TTS model parameters for audio synthesis
These methods abstract provider-specific implementation details, allowing the system to support multiple LLM and TTS backends without modifying the core generation logic.
Summary
- Domain models in
open_notebook/podcasts/models.pydefineEpisodeProfile,SpeakerProfile, andPodcastEpisodefor persistent configuration and state management across the generation lifecycle. - Asynchronous execution via
commands/podcast_commands.pyleverages the surreal-commands framework for crash-resilient job processing and recovery. - API abstraction provided by
api/podcast_service.pyenables HTTP-based interaction with validation, job triggering, and status polling capabilities. - Model registry delegation through
resolve_outline_config(),resolve_transcript_config(), andresolve_tts_config()methods enables flexible multi-provider support.
Frequently Asked Questions
How does Open-Notebook handle multiple speakers in podcast generation?
Open-Notebook supports 1-4 speakers through the SpeakerProfile model, which stores individual voice_id, backstory, and personality traits for each participant. The generate_podcast command in commands/podcast_commands.py coordinates multi-voice synthesis by iterating through the speakers list and invoking the TTS provider specified in voice_model for each distinct voice.
What happens if a podcast generation job fails mid-process?
The system uses surreal-commands for durable job queue management. The PodcastEpisode model maintains a command reference that links the domain entity to the job queue state, enabling automatic crash recovery and status polling. Failed jobs can be retried without losing the episode configuration or partial progress stored in the outline and transcript fields.
How do I configure different LLM providers for outline and transcript generation?
The EpisodeProfile model exposes separate outline_llm and transcript_llm fields, allowing distinct model selection for each generation phase. The resolve_outline_config() and resolve_transcript_config() methods delegate to open_notebook.ai.models.Model to fetch provider-specific parameters, enabling flexible backend selection without modifying the core pipeline logic.
Where does Open-Notebook store generated podcast audio files?
The PodcastEpisode model persists the audio_file path, which references the final synthesized audio location. The actual storage mechanism depends on the TTS provider configuration resolved through resolve_tts_config(), while the PodcastService in api/podcast_service.py handles URL generation and secure retrieval for client applications.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →