Sebastien Rousseau

Àkàndé: GPT-Powered Voice Assistant for Executives

ארכיטקטורה של עוזר קולי פתוח ב-Python: Whisper, GPT-4, מטמון SQLite ו-fpdf2

5 דקות קריאה
Banner for: Àkàndé: GPT-Powered Voice Assistant for Executives

סיכום מנהלים / נקודות עיקריות

  • Àkàndé ⧉ הוא עוזר קולי בקוד פתוח בשפת Python המשרשר את OpenAI Whisper להמרת דיבור לטקסט, השלמות צ'אט GPT-4, מטמון תגובות SQLite מקומי וייצוא PDF של fpdf2 לתזרים עבודה בודד המונע בקול, שאינו דורש אחסון בענן ואינו דורש משקלי מודל AI מקומיים.
  • מטמון SQLite שומר hash-ים SHA-256 של מחרוזות שאילתה מנורמלות הממופות לטקסט תגובת ה-API הגולמי; פגיעות במטמון עולות אפס טוקנים ומוחזרות בפחות מ-10 מ"ש, מה שהופך שאילתות חוזרות (כמו סקירת החלטה מוקדמת יותר בישיבה) לחינמיות בעיקרן.
  • שיחה רב-תורות נשמרת על ידי בניית רשימת ה-messages בזיכרון והעברתה בכל קריאת Chat Completions API — המודל מקבל את היסטוריית הסשן המלאה כדי שיוכל להתייחס לחליפות קודמות, במחיר של שימוש הולך וגדל בטוקנים בכל תור.
  • יצירת סיכום PDF מסריאלת את רשימת ה-messages של הסשן למסמך fpdf2 מעוצב: תורות המשתמש והעוזר מסומנים, חותמות זמן מוכנסות, ועימוד אוטומטי מטפל בסשנים בכל אורך שהוא; הקובץ נכתב למערכת הקבצים המקומית ולא מועלה.
  • גבול הפרטיות: רק השאילתה החיה (והיסטוריית הסשן עד לגבול חלון ההקשר) יוצאת מהמכשיר — לא הקלטות אודיו, לא תמלילים ולא תגובות שמורות במטמון נשלחות לשום שירות מרוחק מלבד ה-API של OpenAI.

Àkàndé ⧉ הוא עוזר קולי בקוד פתוח בשפת Python הבנוי סביב שלושה רכיבים הניתנים לשילוב: OpenAI Whisper לזיהוי דיבור, ה-API של GPT-4 Chat Completions להבנה וייצור שפה, ומסד נתונים SQLite מקומי לאחסון תגובות במטמון ושמירת הסשן. התוצאה היא תזרים עבודה המונע בקול שניתן להפעיל על מחשב נייד ללא משקלי מודל מקומיים, תשתית אחסון לא מקוונת או ערימת קונטיינרים.

מאמר זה מתאר את הארכיטקטורה הטכנית של כל רכיב, את החלטות העיצוב סביב אחסון במטמון והקשר רב-תורות, ואת צינור ייצוא ה-PDF.

סקירת הצינור #

אינטראקציה בודדת עם Àkàndé עוקבת אחר הרצף הזה:

  1. לכידת אודיו — המשתמש מדבר; האפליקציה מקליטה אודיו לקובץ WAV זמני באמצעות sounddevice או ספריית אודיו תואמת.
  2. המרת דיבור לטקסט — קובץ ה-WAV נשלח ל-openai.audio.transcriptions.create() (Whisper API); התמליל מוחזר כמחרוזת פשוטה.
  3. חיפוש במטמון — התמליל מנורמל (אותיות קטנות, רווחים דחוסים) ומוכנס ל-hash SHA-256; ה-hash נחפש בטבלת ה-SQLite המקומית response_cache.
  4. קריאת API או פגיעה במטמון — במקרה של החמצה, התמליל מצורף לרשימת ה-messages של הסשן ונשלח ל-openai.chat.completions.create(); טקסט התגובה נשמר במטמון.
  5. המרת טקסט לדיבור — טקסט התגובה מומר לאודיו באמצעות נקודת הקצה openai.audio.speech.create() (TTS) או ספריית TTS מקומית, ומושמע.
  6. ייצוא PDF (על פי דרישה) — רשימת ה-messages המלאה מסורייאלת למסמך fpdf2 מעוצב ונכתבת לדיסק.

שילוב עם OpenAI: Chat Completions ו-Whisper #

Àkàndé משתמש ב-openai Python SDK הן לזיהוי דיבור והן ליצירת טקסט. קריאת תמלול Whisper:

with open(audio_file_path, "rb") as f:
    transcript = openai.audio.transcriptions.create(
        model="whisper-1",
        file=f,
        language=None  # auto-detect
    )
user_text = transcript.text

קריאת Chat Completions שומרת רשימת messages בהיקף סשן:

messages.append({"role": "user", "content": user_text})

response = openai.chat.completions.create(
    model="gpt-4-turbo-preview",
    messages=messages,
    temperature=0.2,
    max_tokens=1024
)

assistant_text = response.choices[0].message.content
messages.append({"role": "assistant", "content": assistant_text})

הפרומפט של המערכת מוצמד פעם אחת בתחילת הסשן ושולט בפרסונה של Àkàndé, בתבנית הפלט ובכל אילוצים ספציפיים לתחום:

messages = [
    {
        "role": "system",
        "content": (
            "You are Àkàndé, a concise executive assistant. "
            "Respond in plain prose. Do not use markdown. "
            "If asked to summarise, produce three bullet points maximum."
        )
    }
]

הגדרת temperature=0.2 מחליפה גיוון יצירתי בדטרמיניזם — חשוב לשאילתות עובדתיות כמו שחזור החלטה מוקדמת יותר בסשן.

מטמון תגובות SQLite #

סכמת המטמון מינימלית:

CREATE TABLE IF NOT EXISTS response_cache (
    query_hash  TEXT PRIMARY KEY,
    response    TEXT NOT NULL,
    created_at  INTEGER NOT NULL  -- Unix timestamp
);

נתיב החיפוש והכתיבה:

import hashlib, sqlite3, time

def _normalise(text: str) -> str:
    return " ".join(text.lower().split())

def cache_get(conn: sqlite3.Connection, query: str) -> str | None:
    h = hashlib.sha256(_normalise(query).encode()).hexdigest()
    row = conn.execute(
        "SELECT response FROM response_cache WHERE query_hash = ?", (h,)
    ).fetchone()
    return row[0] if row else None

def cache_set(conn: sqlite3.Connection, query: str, response: str) -> None:
    h = hashlib.sha256(_normalise(query).encode()).hexdigest()
    conn.execute(
        "INSERT OR REPLACE INTO response_cache VALUES (?, ?, ?)",
        (h, response, int(time.time()))
    )
    conn.commit()

INSERT OR REPLACE מבטיח עדכון תגובה שמורה במטמון אם אותה שאילתה נשלחת לאחר שדרוג מודל. שאילתת פינוי מבוססת TTL (DELETE WHERE created_at < ?) ניתנת לתזמון בהפעלה כדי לתחום את גודל המטמון.

ביצועי פגיעה במטמון: חיפוש SQLite ב-SSD מקומי מחזיר תוצאה בפחות מ-1 מ"ש לטבלאות עד ~100,000 שורות. זמן ה-round-trip לקריאת GPT-4 API חיה הוא בדרך כלל 600–900 מ"ש לתגובות קצרות. לתדרוך יומי עם מספר שאילתות חוזרות, המטמון מבטל את רוב קריאות ה-API לאחר הסשן הראשון.

יצירת סיכום PDF #

ייצוא PDF משתמש ב-fpdf2, ספריית Python PDF מתוחזקת ללא תלויות בינאריות:

from fpdf import FPDF
from datetime import datetime

def export_session_pdf(messages: list[dict], output_path: str) -> None:
    pdf = FPDF()
    pdf.add_page()
    pdf.set_font("Helvetica", size=11)
    pdf.set_margins(20, 20, 20)

    pdf.set_font("Helvetica", "B", 14)
    pdf.cell(0, 10, f"Àkàndé Session — {datetime.now():%Y-%m-%d %H:%M}", ln=True)
    pdf.ln(4)

    for msg in messages:
        if msg["role"] == "system":
            continue
        label = "You" if msg["role"] == "user" else "Àkàndé"
        pdf.set_font("Helvetica", "B", 10)
        pdf.cell(0, 6, label, ln=True)
        pdf.set_font("Helvetica", size=10)
        pdf.multi_cell(0, 5, msg["content"])
        pdf.ln(3)

    pdf.output(output_path)

multi_cell() מטפל בגלישת שורות ובמעברי עמוד אוטומטיים, כך שסשנים בכל אורך שהוא מייצרים מסמך מעוצב היטב ללא לוגיקת עימוד ידנית. הפלט הוא קובץ תואם PDF/A ללא גופנים מוטמעים מעבר למדדי Helvetica הסטנדרטיים.

מודל הפרטיות #

גבול הפרטיות ב-Àkàndé מוגדר על ידי שלושה עובדות:

  1. האודיו נשלח ל-Whisper API דרך HTTPS ואינו נשמר על ידי OpenAI מעבר לקריאת ה-API (בהתאם למדיניות השימוש בנתוני ה-API של OpenAI נכון לפברואר 2024).
  2. קריאות Chat Completions API מעבירות את רשימת ה-messages של הסשן — שעשויה להכיל את היסטוריית השיחה המלאה לסשנים רב-תורות.
  3. מסד הנתונים SQLite וקובצי ה-PDF חיים לחלוטין במערכת הקבצים המקומית; לא מתרחשת סנכרון ברקע לשום שירות ענן.

עבור מקרי שימוש בכירים הכרוכים בנושאים רגישים — דיוני M&A, עניינים אנושיים, אסטרטגיה רגולטורית — יש לסקור את היסטוריית הסשן המועברת ל-API אל מול מדיניות השימוש ב-AI של הארגון לפני הפריסה. ניתן להשתמש בגבול max_tokens בפרומפט המערכת כדי למנוע העברה בלתי מכוונת של הקשר העולה על היקף הגילוי המיועד.

שאלות נפוצות #

האם Àkàndé שומר את היסטוריית השיחה לאחר סיום הסשן? רשימת ה-messages שבזיכרון מושלכת כאשר התהליך יוצא. היסטוריית השיחה נשמרת רק אם המשתמש מפעיל ייצוא PDF או אם מוסיפים שכבת התמדה מותאמת אישית. מטמון ה-SQLite שומר hash-ים של שאילתות וטקסט תגובות, לא את הקשר השיחה המלא.

כיצד המטמון מטפל בשאילתות דומות אך לא זהות? המטמון משתמש ב-hash של התאמה מדויקת על מחרוזת השאילתה המנורמלת. שתי שאילתות הנבדלות במילה אחת יפיקו hash-ים שונים ויגרמו לקריאות API נפרדות. אחסון סמנטי במטמון (שימוש בדמיון הטמעות להתאמת שאילתות כמעט כפולות) ידרוש שלב חיפוש וקטורי נוסף ואינו חלק מהיישום הבסיסי.

באיזה מודל GPT משתמש Àkàndé כברירת מחדל? ברירת המחדל היא gpt-4-turbo-preview נכון לפברואר 2024. שם המודל הוא פרמטר תצורה, כך שניתן להחליף כל מודל השלמת צ'אט של OpenAI. מעבר ל-gpt-3.5-turbo מפחית את עלות ה-API בכ-20× לטוקן אך מפחית את איכות ההנמקה לשאילתות מורכבות בריבוי שלבים.

האם ניתן להתאים אישית את פורמט ייצוא ה-PDF? כן. פונקציית ייצוא fpdf2 מקבלת את רשימת ה-messages כקלט הנדרש היחיד שלה, כך שניתן לשנות גופן, שוליים, גודל עמוד, תוכן כותרת ותיוג על ידי עריכת פונקציית הייצוא. fpdf2 תומך גם בהוספת תמונות, טבלאות וגופני Unicode, המאפשרים פריסות מסמך עשירות יותר לארגונים עם דרישות מיתוג ספציפיות.

הפניות #

  1. OpenAI. Audio Transcriptions — Whisper API. OpenAI Platform Documentation, 2024. https://platform.openai.com/docs/api-reference/audio/createTranscription
  2. OpenAI. Chat Completions API. OpenAI Platform Documentation, 2024. https://platform.openai.com/docs/api-reference/chat/create
  3. Voss, J. ואחרים. fpdf2: Modern PDF generation for Python. GitHub, 2024. https://github.com/py-pdf/fpdf2
  4. SQLite Consortium. SQLite Documentation. sqlite.org, 2024. https://www.sqlite.org/docs.html

נסקר לאחרונה .

נסקר לאחרונה .