IT ▾
Ottieni la chiave API

Appunti riunione LLM API: da trascrizione a sintesi in Python

Per ottenere gli appunti della riunione LLM API invii la trascrizione a un endpoint di chat completions con un breve system prompt e leggi la risposta. I fattori che determinano la qualità sono il prompt, una forma di output fissa e come gestisci le registrazioni lunghe.

Aggiornato

Tavolo da riunione isometrico con nuvolette di dialogo che si condensano in una scheda checklist sopra

Punti chiave

  • Una singola chiamata di completamento chat trasforma una trascrizione in appunti; la modalità JSON ti offre una forma fissa.
  • Una finestra di contesto da 100.000 token contiene la maggior parte delle trascrizioni di riunioni senza segmentazione.
  • Indica al modello di scrivere null per i proprietari e le date mancanti, così non li inventa.
  • Una chiave completa permette 8 richieste concorrenti, sufficienti per elaborare una giornata di riunioni in parallelo.

La pipeline in quattro passaggi

  1. Registra e trascrivi. Usa qualsiasi strumento di riconoscimento vocale. Questa API è solo per testo e non accetta audio.
  2. Prepara il testo. Aggiungi un'intestazione con il titolo della riunione, la data e i nomi dei partecipanti. Le etichette degli speaker, se le hai, aiutano molto.
  3. Chiama il modello. Invia la trascrizione con un system prompt che definisce le sezioni che desideri.
  4. Archivia e condividi il risultato. Salva il JSON, rendilo come Markdown o HTML, pubblicalo dove il team legge.

L'endpoint è POST /v1/chat/completions su https://api.whisperapis.com/v1, l'ID del modello è uncensored e qualsiasi SDK OpenAI funziona dopo aver modificato l'URL di base e la chiave. Se devi prima configurare il riconoscimento vocale, la guida quickstart copre la parte testuale e qualsiasi server compatibile con Whisper può fornire la trascrizione.

Ottieni appunti strutturati con la modalità JSON

Le sintesi libere vanno bene per la lettura, ma una pipeline vuole campi che può archiviare e filtrare. La modalità JSON, abilitata impostando response_format su {"type": "json_object"}, fa sì che il modello restituisca un singolo oggetto JSON. Descrivi le chiavi nel system prompt e usa la parola JSON lì, perché è il prompt a definire la forma.

import json
from openai import OpenAI

client = OpenAI(base_url="https://api.whisperapis.com/v1", api_key="YOUR_KEY")

SYSTEM = """You write meeting notes from raw transcripts.
Use only what the transcript says. If an owner or a date is not stated, write null.
Reply with a JSON object with the keys: summary (string), decisions (array of strings),
action_items (array of objects with task, owner, due), open_questions (array of strings)."""

transcript = open("standup.txt", encoding="utf-8").read()

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": SYSTEM},
        {"role": "user", "content": "Transcript:\n\n" + transcript},
    ],
    response_format={"type": "json_object"},
    temperature=0.2,
)

notes = json.loads(resp.choices[0].message.content)
for item in notes["action_items"]:
    print(item["owner"], "->", item["task"], item["due"])

Due righe in quel prompt fanno la maggior parte del lavoro. "Usa solo ciò che dice la trascrizione" impedisce al modello di aggiungere dettagli plausibili. "Se un proprietario o una data non sono indicati, scrivi null" gli dà un modo legale per dire che non lo sa, il che è meglio di un nome inventato. Una temperatura bassa come 0,2 riduce la variazione tra le esecuzioni, cosa che vuoi quando la stessa trascrizione potrebbe essere elaborata due volte.

Analizza sempre in modo difensivo. Avvolgi json.loads in un blocco try e in caso di errore ritenta una volta. Le richieste fallite non vengono addebitate e un singolo tentativo risolve la maggior parte degli errori di formattazione occasionale.

Trasmetti il risultato alla persona in attesa

Se qualcuno clicca un pulsante e aspetta gli appunti, mostra il testo man mano che arriva. Imposta stream su true e l'API invia eventi server-sent; l'utilizzo è incluso alla fine dello stream.

from openai import OpenAI

client = OpenAI(base_url="https://api.whisperapis.com/v1", api_key="YOUR_KEY")
transcript = open("standup.txt", encoding="utf-8").read()

stream = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": "Write concise meeting notes in Markdown with headings: Summary, Decisions, Actions."},
        {"role": "user", "content": transcript},
    ],
    stream=True,
    temperature=0.3,
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Lo streaming ha un dettaglio operativo: una richiesta in streaming occupa la sua slot di concorrenza fino alla fine dello stream. Una chiave completa permette 8 richieste alla volta, una chiave di prova 2. Se una scheda del browser si chiude e il tuo server continua a leggere, quella slot rimane occupata, quindi annulla la richiesta upstream quando il client si disconnette.

Per i lavori batch che nessuno osserva, salta lo streaming. Una richiesta normale è più semplice e ottieni l'intera risposta in un unico oggetto.

Riunioni lunghe e la finestra da 100k

La finestra di contesto è di 100,000 token, contando prompt e risposta insieme. Una riunione di un'ora è di circa 9,000 parole, o circa 12,000 token, quindi anche un workshop di un'intera giornata entra in una singola richiesta. Questo rimuove il solito design map-and-reduce in cui dividi una trascrizione, riassumi ogni parte e poi riassumi i riassunti. Ogni passaggio di quel design perde dettagli e una decisione presa al minuto 5 e rivista al minuto 50 è facile da segnalare erroneamente.

Controlla comunque la dimensione prima di inviare. Un controllo grezzo è caratteri divisi per quattro per il testo inglese. Se sei vicino al limite, ci sono due opzioni pulite:

  • Dividi alle interruzioni naturali come gli elementi dell'agenda, riassumi ciascuna e passa gli appunti parziali a una chiamata finale che li unisce.
  • Elimina i contenuti che non contano, come lunghi tratti di chiacchiere prima dell'inizio della riunione.

Il corpo della richiesta massimo è di 8 MB, che non è un limite pratico per il testo. I prompt non vengono utilizzati per l'addestramento, il che è importante se le registrazioni includono piani interni o nomi di clienti.

Dettagli del prompt che cambiano l'output

Di chi sono gli appunti

"Appunti per un ingegnere che ha perso la riunione" ottiene dettagli diversi da "un aggiornamento di un paragrafo per il team esecutivo". Scrivi il lettore nel system prompt.

Fornisci al modello la lista dei partecipanti

Lo speech-to-text spesso storpa i nomi. Una riga come "Partecipanti: Priya Nair (PM), Tom Ortiz (backend), Lena Fischer (design)" permette al modello di riparare una trascrizione che dice "Tom Ortis" e di assegnare i compiti alla persona giusta.

Chiedi decisioni e azioni separatamente

Una decisione è qualcosa su cui il gruppo è d'accordo. Un'azione è qualcosa che una persona farà. Quando entrambi vivono in un unico elenco, i lettori lo saltano. Chiavi separate rendono la distinzione esplicita e il modello la segue in modo coerente.

Mantieni le parti sensibili

Le riunioni reali contengono linguaggio schietto, lamentele su persone nominate, preoccupazioni legali e dispute accese. Il modello qui è ottimizzato per rispondere senza rifiuti di contenuto per l'uso adulto legale, quindi riassume ciò che è stato detto invece di rifiutarsi. Possiedi ancora l'output, quindi rivedi gli appunti prima che vengano inviati alle persone che non erano nella stanza.

Gestire un'intera giornata di riunioni

Un team che registra sei riunioni al giorno può elaborarle in parallelo. Con 8 richieste parallele, invia fino a otto alla volta; un piccolo pool di worker con un semaforo fa il lavoro. Il limite per minuto per una chiave completa è di 300 richieste, che una pipeline di riunione non raggiungerà.

Node funziona allo stesso modo di Python. Ecco la versione non in streaming:

import OpenAI from "openai";
import { readFileSync } from "node:fs";

const client = new OpenAI({
  baseURL: "https://api.whisperapis.com/v1",
  apiKey: process.env.API_KEY,
});

const transcript = readFileSync("standup.txt", "utf8");

const resp = await client.chat.completions.create({
  model: "uncensored",
  messages: [
    { role: "system", content: "Summarize the meeting in five bullets, then list action items with owners." },
    { role: "user", content: transcript },
  ],
  temperature: 0.2,
});

console.log(resp.choices[0].message.content);

Se ricevi HTTP 429, leggi il codice di errore. concurrency significa troppe richieste contemporaneamente, quindi riduci la dimensione del pool. rate_limited significa troppe al minuto. Un 429 con un'intestazione Retry-After: 5 segnala un sovraccarico temporaneo; aspetta cinque secondi e riprova.

Verificare gli appunti prima di fidarsi

Gli appunti generati leggono con sicurezza anche quando sono sbagliati, quindi inserisci alcuni controlli economici nella pipeline invece di fare affidamento su un essere umano per notarlo.

  • Controllo citazione. Chiedi una breve citazione di supporto con ogni elemento di azione, poi cerca la trascrizione per essa. Una citazione che non appare è un segno che l'elemento è stato inventato.
  • Controllo proprietario. Confronta ogni proprietario con la tua lista dei partecipanti e segnala i nomi che non sono in essa.
  • Controllo vuoto. Una riunione senza decisioni è possibile, ma un risultato con tutti gli array vuoti su una trascrizione di 40 minuti di solito significa che l'input è stato troncato o il file era sbagliato.
  • Controllo lunghezza. Appunti più lunghi di circa un quinto della trascrizione non sono appunti; stringi il prompt o imposta max_tokens.

Registra l'intestazione di risposta X-Request-Id accanto a ogni risultato salvato. Quando qualcuno dice che un elemento di azione è sbagliato, quell'identificatore ti permette di trovare la richiesta e confrontarla con la trascrizione. Mantenere la trascrizione originale accanto agli appunti è economico e risolve la maggior parte delle dispute rapidamente.

Costo e primo test

Il prezzo è $0,15 per milione di token di input e $0,50 per milione di token di output. Una riunione di un'ora con una trascrizione da 12.000 token e un set di appunti da 800 token costa $0,0018 per l'input e $0,0004 per l'output, quindi $0,0022 in totale. A quel tasso $1 copre circa 454 riunioni del genere. Vedi la pagina dei prezzi per le ricariche, che partono da $20 e possono essere pagate con carta o cripto.

Per provarlo, registrati e apri la pagina delle chiavi API. Una prova gratuita di $0,50 con un clic è disponibile una volta per persona, valida per 7 giorni, senza carta. Esegui lo script Python sopra su una vera trascrizione, leggi il JSON e regola il prompt fino a quando gli elementi di azione corrispondono a quanto accaduto nella riunione. Poi ripeti per il resto.

Domande e risposte

Posso inviare registrazioni audio direttamente?

No. L'API accetta solo testo. Trascrivi la registrazione con uno strumento di riconoscimento vocale, poi invia la trascrizione.

Come rendo coerente il formato dell'output?

Usa la modalità JSON con un prompt di sistema che elenchi ogni chiave e imposta una temperatura bassa. Analizza il risultato in un blocco try e riprova una volta in caso di errore.

Quanto può essere lunga una trascrizione in una singola richiesta?

La finestra di contesto è di 100.000 token per prompt più risposta. Questo copre un workshop di un'intera giornata nella maggior parte dei casi.

Le mie trascrizioni vengono usate per l'addestramento?

No, i prompt non vengono usati per l'addestramento.

Quanto costa una riunione?

Una riunione di un'ora con una trascrizione da 12.000 token e un riassunto da 800 token costa circa $0,0022 a $0,15 e $0,50 per milione di token di input e output.

La tua chiave è a un modulo di distanza

Crea un account, copia la chiave, modifica l'URL di base. È tutta la configurazione.

Ottieni la chiave API