Notatki ze spotkań przez API LLM: od transkrypcji do streszczenia w Pythonie
Aby uzyskać notatki z API LLM, wyślij transkrypcję do endpointu chat completions z krótkim promptem systemowym i przeczytaj odpowiedź. Kluczowe dla jakości są prompt, stały kształt wyjścia oraz sposób obsługi długich nagrań.
Zaktualizowano

Kluczowe punkty
- Jedno wywołanie chat completion przekształca transkrypcję w notatki; tryb JSON zapewnia stały format.
- Okno 100 000 tokenów pomieści większość transkrypcji spotkań bez dzielenia na fragmenty.
- Poinstruuj model, aby wpisywał null dla brakujących właścicieli i dat, aby nie wymyślał ich samodzielnie.
- Pełny klucz pozwala na 8 zapytań współbieżnych, co wystarcza do przetworzenia całodniowych spotkań równolegle.
Pipeline w czterech krokach
- Nagraj i ztranskrybuj. Użyj dowolnego narzędzia do konwersji mowy na tekst. To API przyjmuje tylko tekst i nie obsługuje audio.
- Przygotuj tekst. Dodaj nagłówek z tytułem spotkania, datą i imionami uczestników. Etykiety mówców, jeśli są dostępne, bardzo pomagają.
- Wywołaj model. Wyślij transkrypcję z promptem systemowym definiującym sekcje, które chcesz uzyskać.
- Zapisz i udostępnij wynik. Zapisz JSON, wyrenderuj go jako Markdown lub HTML i opublikuj tam, gdzie zespół czyta notatki.
Endpoint to POST /v1/chat/completions na https://api.whisperapis.com/v1, ID modelu to uncensored, a dowolne SDK OpenAI zadziała po zmianie Base URL i klucza. Jeśli najpierw potrzebujesz skonfigurować konwersję mowy na tekst, dokumentacja quickstart opisuje część tekstową, a dowolny serwer kompatybilny z Whisper może dostarczyć transkrypcję.
Uzyskaj strukturalne notatki w trybie JSON
Streszczenia swobodne są dobre do czytania, ale pipeline wymaga pól, które można zapisać i filtrować. Tryb JSON, włączany przez response_format ustawione na {"type": "json_object"}, zmusza model do zwrócenia jednego obiektu JSON. Opisz klucze w promptie systemowym i użyj słowa JSON, ponieważ to prompt definiuje kształt.
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"])Dwa wiersze w tym promptie wykonują większość pracy. "Używaj tylko tego, co mówi transkrypcja" zapobiega dodawaniu prawdopodobnych detali. "Jeśli właściciel lub data nie są podane, wpisz null" daje modelowi dozwoloną możliwość stwierdzenia, że czegoś nie wie, co jest lepsze niż wymyślenie nazwy. Niska temperatura, np. 0,2, zmniejsza zmienność między uruchomieniami, co jest ważne, gdy ta sama transkrypcja może być przetwarzana dwukrotnie.
Zawsze parsuj defensywnie. Owiń json.loads w bloku try, a w przypadku błędu wykonaj ponowne wywołanie raz. Nieudane żądania nie są rozliczane, a pojedyncze ponowne wywołanie naprawa większość błędów formatowania.
Strumieniuj wynik do oczekującej osoby
Jeśli ktoś kliknie przycisk i czeka na notatki, pokazuj tekst w miarę jego przybywania. Ustaw stream na true, a API wysyła zdarzenia wysyłane przez serwer; zużycie jest uwzględnione na końcu strumienia.
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)Strumieniowanie ma jeden szczegół operacyjny: strumieniowane zapytanie zajmuje slot współbieżności do końca strumienia. Pełny klucz pozwala na 8 jednocześnie, klucz próbny na 2. Jeśli karta przeglądarki zostanie zamknięta, a twój serwer nadal czyta strumień, slot pozostaje zajęty, więc anuluj zapytanie do upstreamu, gdy klient się rozłączy.
W zadaniach batchowych, których nikt nie obserwuje, pomiń strumieniowanie. Zwykłe żądanie jest prostsze, a odpowiedź otrzymasz jako jeden obiekt.
Długie spotkania i okno 100k
Okno kontekstu wynosi 100 000 tokenów, licząc razem prompt i odpowiedź. Jedno godzinne spotkanie to około 9 000 słów, czyli około 12 000 tokenów, więc nawet całodniowy warsztat mieści się w jednym zapytaniu. To eliminuje typowy wzorzec map-reduce, w którym dzieli się transkrypcję, streszcza każdą część, a następnie streszcza streszczenia. Każda taka operacja traci szczegóły, a decyzja podjęta na minutę 5 i zrewidowana na minutę 50 jest łatwa do błędnego raportowania.
Nadal sprawdzaj rozmiar przed wysłaniem. Prymitywna ocena to podzielenie liczby znaków przez cztery dla tekstu angielskiego. Jeśli jesteś blisko limitu, masz dwie czyste opcje:
- Podziel na naturalne przerwy, takie jak punkty agendy, zsumuj każdy fragment i przekaż częściowe notatki do końcowego wywołania, które je połączy.
- Usuń treści, które nie mają znaczenia, np. długie fragmenty luźnej rozmowy przed rozpoczęciem spotkania.
Maksymalny rozmiar ciała żądania to 8 MB, co nie jest praktycznym limitem dla tekstu. Prompty nie są używane do trenowania, co ma znaczenie, jeśli nagrania zawierają wewnętrzne plany lub nazwy klientów.
Szczegóły promptu, które zmieniają wynik
Określ, dla kogo są notatki
"Notatki dla inżyniera, który przegapił spotkanie" wymagają innej szczegółowości niż "jednoakapitowy raport dla zarządu". Wpisz odbiorcę w prompt systemowy.
Podaj modelowi listę uczestników
Konwersja mowy na tekst często zniekształca nazwiska. Wiersz "Uczestnicy: Priya Nair (PM), Tom Ortiz (backend), Lena Fischer (design)" pozwala modelowi naprawić transkrypcję mówiącą "Tom Ortis" i przypisać zadania właściwej osobie.
Pytaj o decyzje i działania osobno
Decyzja to coś, na co zgodziła się grupa. Akcja to coś, co jedna osoba wykona. Gdy oba elementy znajdują się na jednej liście, czytelnicy ją pomijają. Oddzielne klaryfikują tę różnicę, a model traktuje je konsekwentnie.
Zachowaj wrażliwe treści
Prawdziwe spotkania zawierają bezpośrednie słowa, skargi na konkretne osoby, wątpliwości prawne i gorące dyskusje. Model jest zoptymalizowany pod kątem odpowiadania bez odrzuceń treści dla prawnego użytku dorosłych, więc podsumowuje to, co powiedziano, zamiast odmawiać. Własność wyjścia należy do Ciebie, więc przejrzyj notatki przed udostępnieniem osobom, które nie były na spotkaniu.
Obsługa całodniowych spotkań
Zespół, który nagrywa sześć spotkań dziennie, może je przetwarzać równolegle. Przy 8 zapytaniach współbieżnych wysyłaj do ośmiu na raz; mała pula workerów z semaforem wykona tę pracę. Limit zapytań na minutę dla pełnego klucza to 300 zapytań, czego pipeline spotkań nie osiągnie.
Node działa tak samo jak Python. Oto wersja niestrumieniowa:
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);Jeśli otrzymasz HTTP 429, przeczytaj kod błędu. concurrency oznacza zbyt wiele żądań naraz, więc zmniejsz rozmiar puli. rate_limited oznacza zbyt wiele na minutę. 429 z nagłówkiem Retry-After: 5 sygnalizuje tymczasowe przeciążenie; poczekaj pięć sekund i spróbuj ponownie.
Sprawdzanie notatek przed zaufaniem
Wygenerowane notatki brzmią pewnie, nawet gdy są błędne, więc dodaj do potoku kilka tanich sprawdzianów zamiast polegać na ludzkiej uwadze.
- Sprawdź cytaty. Poproś o krótki cytat wspierający każde zadanie, a następnie wyszukaj go w transkrypcji. Cytat, który się nie pojawia, jest znakiem, że zadanie zostało wymyślone.
- Sprawdź właścicieli. Porównaj każdego właściciela z listą uczestników i oznacz nazwiska, których nie ma na liście.
- Sprawdzenie pustoty. Spotkanie bez decyzji jest możliwe, ale wynik z pustymi tablicami przy 40-minutowej transkrypcji zwykle oznacza, że dane wejściowe zostały obcięte lub użyto błędnego pliku.
- Sprawdzenie długości. Notatki dłuższe niż około jedna piąta transkrypcji to nie są notatki; zawęź prompt lub ustaw
max_tokens.
Loguj nagłówek odpowiedzi X-Request-Id obok każdego zapisanego wyniku. Kiedy ktoś zgłosi, że element do wykonania jest błędny, ten identyfikator pozwoli Ci znaleźć zapytanie i porównać je z transkrypcją. Przechowywanie oryginalnej transkrypcji obok notatek jest tanie i szybko rozstrzyga większość sporów.
Koszt i pierwszy test
Cena to $0,15 za milion tokenów wejściowych i $0,50 za milion tokenów wyjściowych. Jedno godzinne spotkanie z transkrypcją 12 000 tokenów i zestawem notatek 800 tokenów kosztuje $0,0018 za dane wejściowe i $0,0004 za dane wyjściowe, czyli łącznie $0,0022. Przy takim stawce $1 pokrywa około 454 takich spotkań. Zobacz stronę z cenami, aby doładować konto, które zaczyna się od $20 i można opłacić kartą lub kryptowalutami.
Aby wypróbować, zarejestruj się i otwórz stronę klucza API. Jednoklikowa próba za $0,50 jest dostępna raz na osobę, ważna przez 7 dni, bez karty. Uruchom powyższy skrypt Pythona na prawdziwym transkrypcie, przeczytaj JSON i dostosuj prompt, aż elementy akcji będą zgodne z przebiegiem spotkania. Następnie powtórz proces dla pozostałych.
Więcej przewodników
Pytania i odpowiedzi
Czy mogę wysyłać nagrania audio bezpośrednio?
Nie. API przyjmuje tylko tekst. Najpierw transkrybuj nagranie za pomocą narzędzia do konwersji mowy na tekst, a następnie wyślij transkrypcję.
Jak zapewnić spójny format wyjściowy?
Użyj trybu JSON z promptem systemowym, który wymienia każdy klucz, i ustaw niską temperaturę. Przeparsuj wynik w bloku try i spróbuj ponownie raz w przypadku błędu.
Jaka długość transkrypcji mieści się w jednym zapytaniu?
Okno kontekstu wynosi 100 000 tokenów dla promptu plus odpowiedzi. W większości przypadków obejmuje to całodzielny warsztat.
Czy moje transkrypcje są używane do trenowania?
Nie, prompty nie są używane do trenowania.
Ile kosztuje jedno spotkanie?
Godzinne spotkanie z transkrypcją na 12 000 tokenów i streszczeniem na 800 tokenów kosztuje około $0,0022 przy cenie $0,15 i $0,50 za milion tokenów wejściowych i wyjściowych.
Twój klucz jest o jeden formularz stąd
Utwórz konto, skopiuj klucz, zmień bazowy URL. To cała konfiguracja.