كيف تضيف أداة تفريغ إلى وكيل ذكاء اصطناعي

اجمع استدعاءي KolWrite داخل أداة واحدة باسم transcribe_media. ستجد هنا تعريف الأداة بصيغة tool-use من Anthropic وصيغة function-calling من OpenAI، مع دالة التنفيذ بلغة Python، وحلقة تشغيل بسيطة، وقاعدة قصيرة تضيفها إلى AGENTS.md أو CLAUDE.md لتوجيه وكلاء البرمجة إلى استخدام الواجهة بطريقة صحيحة.

احصل على مفتاح API بدء سريع اللغات المدعومة

آخر تحديث: · Markdown

هل تحتاج فعلًا إلى تعريف أداة؟

إذا كان وكيلك يشغّل أوامر الطرفية (Claude Code وCodex CLI وCursor وWindsurf) فلا يحتاج إلى مخطط: فهو يشغّل curl أو Python، وتشرح له التعليمات في agent-instructions.md الطريقة. أما تعريف الأداة فهو للوكلاء الذين تبنيهم بواجهة برمجية وحلقة أدوات، أو للأُطر التي تستدعي الدوال.

تعريف الأداة: صيغة tool-use من Anthropic

{
  "name": "transcribe_media",
  "description": "Transcribe an audio or video file with the KolWrite API. Returns timed text. Use output_format \"json\" for word timestamps and speakers, \"srt\" for subtitles, \"txt\" for plain text. Billed per second of audio.",
  "input_schema": {
    "type": "object",
    "properties": {
      "path_or_url": { "type": "string", "description": "Local file path or a public URL of an audio or video file." },
      "model": { "type": "string", "enum": ["base", "oracle_mini", "oracle", "oracle_pro", "oracle_max"], "description": "Default oracle. base is cheapest for clear audio; translate_to needs an Oracle model." },
      "language": { "type": "string", "description": "Language code such as en, he, ar, es, or auto to detect." },
      "translate_to": { "type": "string", "description": "Language code to translate into (Oracle models only)." },
      "output_format": { "type": "string", "enum": ["json", "txt", "srt"] },
      "word_timestamps": { "type": "boolean", "description": "Word times in json. For srt, false gives one cue per segment." },
      "include_diarization": { "type": "boolean", "description": "Label who is speaking." },
      "num_speakers": { "type": "integer", "minimum": 1 }
    },
    "required": ["path_or_url"]
  }
}

تعريف الأداة: صيغة function-calling من OpenAI

{
  "type": "function",
  "function": {
    "name": "transcribe_media",
    "description": "Transcribe an audio or video file with the KolWrite API. Returns timed text. Use output_format \"json\" for word timestamps and speakers, \"srt\" for subtitles, \"txt\" for plain text. Billed per second of audio.",
    "parameters": {
      "type": "object",
      "properties": {
        "path_or_url": { "type": "string", "description": "Local file path or a public URL of an audio or video file." },
        "model": { "type": "string", "enum": ["base", "oracle_mini", "oracle", "oracle_pro", "oracle_max"] },
        "language": { "type": "string", "description": "Language code such as en, he, ar, es, or auto to detect." },
        "translate_to": { "type": "string", "description": "Language code to translate into (Oracle models only)." },
        "output_format": { "type": "string", "enum": ["json", "txt", "srt"] },
        "word_timestamps": { "type": "boolean" },
        "include_diarization": { "type": "boolean" },
        "num_speakers": { "type": "integer", "minimum": 1 }
      },
      "required": ["path_or_url"]
    }
  }
}

تعتمد الصيغتان مخطط JSON نفسه للمعاملات. وتضم قائمة enum النماذج المعتمدة حاليًا، بينما يُعدّ core وedge قديمين.

الدالة المشغّلة للأداة

ترفع هذه الدالة الملفات المحلية، وتبدأ المهمة، وتنتظر اكتمالها ثم تعيد ملخصًا للنتيجة. وعند طلب صيغة JSON، تحفظ الدالة الاستجابة الكاملة في ملف وتعيد أسطرًا مرقّمة فقط، لأن قائمة الكلمات الكاملة لتسجيل طويل تفوق حاجة النموذج.

kolwrite.py

# kolwrite.py — three small functions around the KolWrite REST API
import os, time, requests

API = "https://app.kolwrite.com"
HEADERS = {"x-api-key": os.environ["KOLWRITE_API_KEY"]}


def upload(path):
    """Upload a local file (up to 100 MiB) and return a URL the API can read."""
    name = os.path.basename(path)
    form = requests.post(f"{API}/upload", headers=HEADERS, json={"filename": name}, timeout=30)
    form.raise_for_status()
    form = form.json()
    with open(path, "rb") as media:
        # No x-api-key on this request: it goes to the storage address.
        sent = requests.post(form["uploadUrl"], data=form["uploadFields"],
                             files={"file": (name, media)}, timeout=600)
    sent.raise_for_status()
    return form["fileUrl"]


def transcribe(audio_url, timeout_s=3600, **options):
    """Start a job, wait for it, return the result: a dict for json, a string for srt and txt."""
    body = {"audio_url": audio_url, "model": "oracle", **options}
    job = requests.post(f"{API}/transcribe", headers=HEADERS, json=body, timeout=30)
    job.raise_for_status()
    job_id = job.json()["jobId"]
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        time.sleep(5)
        reply = requests.get(f"{API}/transcribe/{job_id}", headers=HEADERS, timeout=30)
        reply.raise_for_status()
        reply = reply.json()
        if reply["status"] == "COMPLETED":
            return reply["result"]
        if reply["status"] == "FAILED":
            raise RuntimeError(reply.get("error", "transcription failed"))
    raise TimeoutError(f"job {job_id} did not finish in {timeout_s} seconds")

tool.py

# tool.py — run a transcribe_media call for the model and keep the reply small
import json
from kolwrite import upload, transcribe  # the helper from the video-editing guide


def numbered_line(number, segment):
    who = f'{segment["speaker"]}: ' if segment.get("speaker") else ""
    return f'S{number} [{segment["start"]:.1f}-{segment["end"]:.1f}] {who}{segment["text"]}'


def run_transcribe_media(path_or_url, output_format="json", **options):
    url = path_or_url if path_or_url.startswith(("http://", "https://")) else upload(path_or_url)
    result = transcribe(url, output_format=output_format, **options)
    if output_format != "json":
        return result  # srt and txt are already strings
    # Long recordings: save the full JSON and hand the model numbered lines, not 500 KB of words.
    with open("transcript.json", "w", encoding="utf-8") as out:
        json.dump(result, out, ensure_ascii=False)
    lines = [numbered_line(i, s) for i, s in enumerate(result["segments"])]
    return "Full JSON saved to transcript.json (words[] has word times).\n" + "\n".join(lines)

حلقة تشغيل بسيطة (Anthropic Messages API)

# loop.py — Anthropic Messages API tool loop around run_transcribe_media
import anthropic
from tool import run_transcribe_media

client = anthropic.Anthropic()          # reads ANTHROPIC_API_KEY
TOOLS = [...]                           # the transcribe_media definition above
messages = [{"role": "user", "content": "Transcribe interview.mp3 and list the questions asked, with times."}]

while True:
    reply = client.messages.create(model="YOUR_MODEL", max_tokens=2000, tools=TOOLS, messages=messages)
    messages.append({"role": "assistant", "content": reply.content})
    if reply.stop_reason != "tool_use":
        print("".join(block.text for block in reply.content if block.type == "text"))
        break
    results = []
    for block in reply.content:
        if block.type == "tool_use" and block.name == "transcribe_media":
            results.append({"type": "tool_result", "tool_use_id": block.id,
                            "content": run_transcribe_media(**block.input)})
    messages.append({"role": "user", "content": results})

استبدل YOUR_MODEL بمعرّف النموذج الذي تعمل عليه. تستمر هذه الحلقة في العمل حتى يتوقف النموذج عن طلب الأدوات. ويمكنك ربط دالة التنفيذ نفسها بأي إطار عمل يدعم استدعاء دوال Python.

قاعدة لملفي AGENTS.md وCLAUDE.md

أضف هذا المقطع إلى ملف المشروع الذي يقرؤه وكيل البرمجة، ليستخدم في كل جلسة نقطة النهاية الصحيحة ويتعامل مع المفتاح والصيغ كما يجب:

## Transcription
For speech-to-text, subtitles and word timings use the KolWrite API (https://app.kolwrite.com).
Before writing code read https://console.kolwrite.com/agent-instructions.md and /llms-full.txt.
- Key: KOLWRITE_API_KEY in the environment, sent as the x-api-key header. Never print it or commit it.
- POST /transcribe {"audio_url", "model": "oracle", "output_format": "json"}, then poll GET /transcribe/{jobId}.
- Local files: POST /upload first and use fileUrl as audio_url. Extract audio from video with ffmpeg to stay under 100 MiB.
- Subtitles: output_format "srt" with "word_timestamps": false (one cue per segment). Formats are json, txt, srt only.
- Always send "model". Ask me before transcribing anything longer than one hour: it costs money.

ضبط التكلفة عند استخدام الوكلاء

  • يُحاسب التفريغ على كل ثانية صوت، بدءًا من 0.48 دولار للساعة على النموذج base. لذلك تُلزم القاعدة السابقة الوكيل باستئذانك قبل تفريغ الملفات الطويلة.
  • خزّن النتائج مؤقتًا: احفظ ملف JSON بجانب ملف الوسائط وأعد استخدامه بدلًا من تفريغ الملف مرة أخرى.
  • اختر أرخص نموذج يناسب مهمتك. استخدم base للصوت الواضح، وoracle لجودة الإنتاج، وoracle_mini إذا كنت تحتاج إلى ترجمة أيضًا.
  • لا يستطيع الوكيل التسجيل بنفسه، لذا يجب أن ينشئ شخص الحساب ومفتاح الواجهة. مرّر المفتاح إليه عبر متغير بيئة.

أسئلة وأجوبة

هل توجد حزمة SDK أو خادم MCP لـ KolWrite؟

لا توجد وقت الكتابة حزمة SDK ولا خادم MCP منشوران. الواجهة HTTPS وJSON؛ فاستخدم تعريف الأداة أعلاه أو curl أو Python مباشرة، أو ولّد عميلًا من openapi.json.

كيف أجعل Claude Code يفرّغ الملفات الصوتية؟

ضع المفتاح في KOLWRITE_API_KEY، وأضف القاعدة أعلاه إلى CLAUDE.md، واطلب التفريغ. يستدعي Claude Code واجهة REST بـ curl أو Python وفق agent-instructions.md.

أي نموذج يجب أن يختاره الوكيل افتراضيًا؟

استخدم oracle للصوت الإنتاجي. أما base فهو الأرخص للصوت الواضح، وoracle_mini هو الأرخص بين النماذج التي تدعم الترجمة. حدّد المعامل model دائمًا في طلبك، لأن الخيار الافتراضي يعود إلى نموذج core القديم.

هل يستطيع الوكيل إنشاء مفتاح API بنفسه؟

لا. يجب أن يسجل شخص في console.kolwrite.com ويشتري الرصيد وينشئ المفتاح، بينما يقرأه الوكيل من متغيرات البيئة فقط.