هذا المقال للمستوى المتوسط — يحتاج إلفة بـ Python وسطر الأوامر، ومفتاح API لـ OpenAI وAnthropic.
اعمل سكريبت يحوّل اجتماعاتك الصوتية لـ Action Items في 15 دقيقة
لو بتقعد بعد كل اجتماع 20 دقيقة تكتب action items من ذاكرتك، أو بتنسى نقطة طلبها العميل تحديدًا، اللي قدامك هنا هيعمل ده بدلك. اجتماع 30 دقيقة بيتلخّص في 90 ثانية بتكلفة قدرها 0.19$.
المشكلة باختصار
الذاكرة بتفقد جزء كبير من تفاصيل أي اجتماع خلال 24 ساعة (Ebbinghaus, 1885). والكتابة اليدوية وقت الاجتماع بتسحب تركيزك من النقاش الفعلي. النتيجة: action items مش واضحة، أصحابها مش متحددين، أو بتتنسى تمامًا.
السكريبت اللي هنبنيه بياخد ملف صوتي ويرجّع ملف Markdown فيه: ملخص في 3 جمل، Action Items مع أصحابها، قرارات اتاخدت، وأسئلة مفتوحة.
مثال بسيط قبل ما ندخل في التفاصيل
تخيّل إنك قاعد مع صديق في كافيه وبيحكيلك خطته للأسبوع. بعد ساعة، انت ممكن تفتكر الفكرة العامة، بس مش هتفتكر إنه قال "الأربع الصبح هطلع للمطار". الـ action item فاتك من غير قصد.
اللي هنعمله ده زي صديق تالت قاعد معاكم بياخد الـ notes الدقيقة دي لوحده، ويرجّعلك ملف منظم بعد ما الاجتماع يخلص.
الفكرة العلمية: pipeline من خطوتين
المعمارية بسيطة، لكن تقسيمها مهم:
- Speech-to-Text (STT): نموذج Whisper من OpenAI بيحوّل الصوت لنص. بيدعم العربي والإنجليزي وممزوجين، ودقّته على الكلام الواضح ~95% حسب ورقة Radford et al. 2022.
- LLM Extraction: نموذج Claude بياخد النص ويستخرج منه action items + decisions + open questions بصيغة JSON ثابتة.
ليه التقسيم ده؟ Whisper متخصص في الصوت، Claude متخصص في فهم السياق. لو حاولت تستعمل Whisper لوحده، مش هيقدر يحلل أو يستنتج المهام. ولو استعملت Claude مع Voice mode مباشرة، هتدفع تكلفة أعلى بكتير.
الخطوات التنفيذية
1. تجهيز البيئة
# انشئ مجلد المشروع
mkdir meeting-extractor && cd meeting-extractor
# بيئة Python معزولة
python3 -m venv .venv && source .venv/bin/activate
# المكتبات المطلوبة
pip install openai anthropic
# المفاتيح
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
2. ملف تحويل الصوت لنص
# stt.py
from openai import OpenAI
client = OpenAI()
def transcribe(audio_path: str, lang: str = "ar") -> str:
with open(audio_path, "rb") as f:
result = client.audio.transcriptions.create(
model="whisper-1",
file=f,
language=lang, # "ar" عربي، "en" إنجليزي
)
return result.text
ملاحظة عملية: حد Whisper API هو 25MB لكل ملف. لو الاجتماع طويل، اضغطه قبل الإرسال:
ffmpeg -i meeting.m4a -ac 1 -ar 16000 -b:a 32k meeting.mp33. ملف استخراج Action Items
# extract.py
import json
import anthropic
client = anthropic.Anthropic()
PROMPT = """انت بتحلل نص اجتماع. ارجع JSON صحيح بهذا الشكل بالظبط:
{
"summary": "ملخص في 3 جمل بحد أقصى",
"action_items": [
{"task": "...", "owner": "...", "due": "..."}
],
"decisions": ["..."],
"open_questions": ["..."]
}
قواعد صارمة:
- لو الـ owner مش مذكور صراحةً، اكتب "غير محدد".
- لو الـ due date مش مذكور، اكتب "غير محدد".
- ممنوع التخمين أو الإضافة من خارج النص.
"""
def extract(transcript: str) -> dict:
msg = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=2000,
messages=[
{"role": "user", "content": f"{PROMPT}\n\n---\nالنص:\n{transcript}"}
],
)
return json.loads(msg.content[0].text)
4. ربط الكل في سكريبت واحد
# main.py
import sys
from stt import transcribe
from extract import extract
audio = sys.argv[1]
print("جاري التفريغ...")
text = transcribe(audio)
print("جاري استخراج المهام...")
result = extract(text)
with open("notes.md", "w", encoding="utf-8") as f:
f.write(f"# اجتماع {audio}\n\n")
f.write(f"## ملخص\n{result['summary']}\n\n")
f.write("## Action Items\n")
for item in result["action_items"]:
f.write(f"- [ ] {item['task']} — `{item['owner']}` ({item['due']})\n")
f.write("\n## القرارات\n")
for d in result["decisions"]:
f.write(f"- {d}\n")
f.write("\n## أسئلة مفتوحة\n")
for q in result["open_questions"]:
f.write(f"- {q}\n")
print("تم → notes.md")
التشغيل:
python main.py meeting-2026-04-26.m4aالتحقق من إنه شغّال
اختبار سريع: سجّل 5 دقائق صوت لوحدك تقول فيها 3 مهام بأسماء مختلفة، وقرار واضح، وسؤال مفتوح. شغّل السكريبت، وافتح notes.md. لو الـ owners اتسجّلوا صح، والـ tasks مش مكررة، والقرار طلع في خانته الصحيحة، الـ pipeline شغّال.
الأرقام الحقيقية
قياس فعلي على اجتماع 30 دقيقة (~3,200 كلمة عربي):
- Whisper API:
0.006$ × 30 = 0.18$ - Claude Haiku 4.5: ~5K input tokens + 600 output ≈ 0.005$
- الزمن الكلي: ~75 ثانية (60 ثانية للتفريغ + 15 للاستخراج)
- المجموع: ~0.19$ لكل اجتماع. فريق بـ 3 اجتماعات يوميًا، 22 يوم عمل = ~12.50$ شهريًا.
قارن ده بـ 20 دقيقة كتابة بعد كل اجتماع × 3 = ساعة في اليوم. لو ساعتك = 30$، التوفير ~660$ شهريًا لكل شخص.
Trade-offs لازم تعرفها قبل ما تتبنّى الحل
- الدقة مش 100%: في اجتماعات بعدة متحدثين، Whisper مش بيفرّق بينهم تلقائيًا. لو محتاج speaker diarization، استخدم WhisperX (مفتوح المصدر) أو AssemblyAI.
- الخصوصية: الصوت بيتبعت لـ OpenAI. للمحادثات الحساسة، شغّل
faster-whisperمحليًا (نموذجlarge-v3~3GB، يشتغل CPU وممكن GPU). - اللهجات والكلام السريع: المصري الفصيح بيتدوّن بـ ~92%، اللهجة الخليجية ~85%، الكلام السريع جدًا أو المتداخل ينزل لـ 80%.
- الاعتماد على JSON: لو الموديل رجّع JSON غير صحيح، السكريبت بيقع. الحل: استخدم Tool use أو response_format بدل ما تعتمد على prompt لوحده.
متى لا تستخدم هذا الحل
- اجتماعات قانونية أو طبية — تحتاج transcription بشري معتمد للأرشفة الرسمية.
- محادثات بـ بيانات صحية أو مالية حساسة — لازم Whisper محلي، أو Azure OpenAI مع BAA، مش الـ public API.
- اجتماعات أقل من 5 دقائق — الكتابة اليدوية أسرع من رفع الملف وانتظار الرد.
- لو فريقك ما بيعمل follow-up على Action Items — السكريبت مش هيحل مشكلة سلوكية. ركّز على الـ tracking الأول.
الخطوة التالية
سجّل اجتماعك الجاي، وشغّل السكريبت. لو الـ Action Items طلعت ناقصة، عدّل الـ PROMPT يطلب صياغة المهمة بصيغة الفعل (مثل "ابعث لـ سارة العرض" بدل "العرض لسارة"). لو الـ owners مش بتظهر، أضف للـ system prompt: "المتحدثون في الاجتماع هم: [قائمة الأسماء]".
المصادر
- OpenAI Whisper API (Speech-to-Text guide):
https://platform.openai.com/docs/guides/speech-to-text - Whisper paper — Radford et al. 2022:
https://cdn.openai.com/papers/whisper.pdf - Anthropic Messages API:
https://docs.anthropic.com/en/api/messages - Anthropic Pricing (Haiku 4.5):
https://docs.anthropic.com/en/docs/about-claude/pricing - Ebbinghaus forgetting curve:
https://en.wikipedia.org/wiki/Forgetting_curve - WhisperX (speaker diarization):
https://github.com/m-bain/whisperX - faster-whisper (تشغيل محلي):
https://github.com/SYSTRAN/faster-whisper