Agent Skills في Claude API: كيفية استخدام مهارة جاهزة دون Claude Code
Markdownكيفية ربط مهارة pptx جاهزة بـ Claude API: container.skills وأداة تنفيذ التعليمات البرمجية والتحقق من الاستجابة وتنزيل العرض التقديمي عبر Files API.
قراءة المقال كاملًا
الخلاصة الرئيسية
يمكن استخدام Agent Skills الجاهزة للمستندات عبر Claude API مباشرةً: حدّد المهارة في container.skills وفعّل code_execution. استخدم في طلبك الأول اقتران النموذج والأداة المتوافق الوارد في المثال الرسمي. نزّل الملف المُنشأ على حدة باستخدام file_id الخاص به؛ يستخدم المثال مفتاح API نفسه للطلب والتنزيل.
يمكنك العثور على تعليمات إضافية في وثائق Ailoot.
ما الذي تحتاج إليه لاستدعاء Agent Skills عبر Claude API؟
هذا الدليل مخصص لاستدعاء API مباشرةً من برنامج، بدلًا من تثبيت مهارة في Claude Code. ستحتاج إلى مفتاح Claude API وإمكانية الوصول إلى النموذج المحدد وPython 3. يستخدم الكود أدناه مكتبة Python القياسية وHTTP، لذا فهو لا يعتمد على إصدار SDK المثبّت لديك. يُمرّر المفتاح عبر متغير البيئة ANTHROPIC_API_KEY؛ لا تضعه في نص البرنامج أو في محادثة.
توفر API مهارات Anthropic جاهزة: pptx للعروض التقديمية، وxlsx لجداول البيانات، وdocx لمستندات Word، وpdf لملفات PDF. تُوصَل هذه المهارات باستخدام type: "anthropic". يستخدم هذا الدليل مهارة جاهزة، من دون تحميل مهارة مخصصة.
تستخدم البدء السريع الرسمي، الذي روجع عند إعداد هذه المادة، الاقتران claude-opus-5-5 وcode_execution_20260521. وهذا هو الاقتران المستخدم أدناه. جرت مراجعة هذا المثال بالاستناد إلى الوثائق؛ وهو ليس تقريرًا عن استدعاء API مدفوع.
ما ترويسات beta المطلوبة؟
يتبع المثال عقد HTTP الحالي الوارد في البدء السريع: الترويسات هي x-api-key وanthropic-version: 2023-06-01 وcontent-type: application/json؛ ولا يرسل anthropic-beta. لا تجمع بين نموذج وطريقة استدعاء وتنسيق استجابة من أجيال مختلفة من الوثائق.
تذكر وثائق Files API أيضًا أن API خرجت من مرحلة beta. تحتفظ الترويسة القديمة files-api-2025-04-14 بتنسيقات الاستجابة القديمة؛ وإزالة الترويسة تنقلها إلى التنسيقات الحالية. لذلك لا يمكن ببساطة الجمع بين مثال قديم يستخدم client.beta.files ومثال جديد.
لسنا بصدد نقل خدمة قائمة من عقد beta القديم هنا. إذا كانت لديك خدمة كهذه بالفعل، فتحقق أولًا من ترويساتها وتنسيقات الاستجابة. وجود كلمة beta في اسم إحدى طرق SDK لا يكفي وحده؛ إذ تشرح وثائق Files API بصورة منفصلة سلوك إصدارات SDK المختلفة.
إنشاء عرض تقديمي وتنزيل الملف
يرسل المثال مهمة لإنشاء خمس شرائح عن الطاقة المتجددة، ويحفظ الاستجابة كاملةً في skill-response.json، ثم يستخرج معرّفات الملفات المُنشأة. ولا يأخذ مسار الحفظ من استجابة النموذج: تُحفظ الملفات في مجلد محلي جديد اسمه skill-output. إذا كان هذا المجلد موجودًا بالفعل، يتوقف البرنامج كي لا يستبدل النتيجة السابقة. يُنشأ المجلد قبل استدعاء API، لذلك يبقى أيضًا إذا فشل الاستدعاء. افحص تلك المحاولة واحتفظ بها قبل أي إجراء جديد؛ ولا تحذف المجلد لمجرد تجاوز خطأ إعادة التشغيل.
import json
import os
from pathlib import Path
from urllib.error import HTTPError
from urllib.request import Request, urlopen
API = "https://api.anthropic.com/v1"
KEY = os.environ["ANTHROPIC_API_KEY"]
HEADERS = {
"x-api-key": KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
}
def request(path, payload=None, binary=False):
data = None if payload is None else json.dumps(payload).encode("utf-8")
req = Request(API + path, data=data, headers=HEADERS)
try:
with urlopen(req, timeout=600) as result:
body = result.read()
except HTTPError as error:
try:
details = json.loads(error.read().decode("utf-8"))
except (ValueError, UnicodeError):
details = {}
info = details.get("error", {})
request_id = error.headers.get("request-id") or details.get("request_id")
diagnostic = {
"http_status": error.code,
"request_id": request_id,
"error_type": info.get("type"),
"message": str(info.get("message", "No JSON error message")).replace(KEY, "[REDACTED]")[:1000],
}
(out / "skill-error.json").write_text(
json.dumps(diagnostic, ensure_ascii=False, indent=2), encoding="utf-8"
)
raise RuntimeError(
f"Claude API HTTP {error.code}; request_id={request_id}; inspect skill-error.json"
) from None
return body if binary else json.loads(body)
out = Path("skill-output")
out.mkdir(exist_ok=False)
response = request("/messages", {
"model": "claude-opus-5-5",
"max_tokens": 16000,
"container": {
"skills": [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}]
},
"messages": [{
"role": "user",
"content": "أنشئ عرضًا تقديميًا عن الطاقة المتجددة من 5 شرائح بلغتي المفضلة.",
}],
"tools": [{"type": "code_execution_20260521", "name": "code_execution"}],
})
(out / "skill-response.json").write_text(
json.dumps(response, ensure_ascii=False, indent=2), encoding="utf-8"
)
print("stop_reason:", response.get("stop_reason"))
file_ids = []
for block in response["content"]:
if block["type"] == "bash_code_execution_tool_result":
result = block["content"]
if result["type"] == "bash_code_execution_result":
for item in result["content"]:
file_id = item.get("file_id")
if file_id and file_id not in file_ids:
file_ids.append(file_id)
if not file_ids:
raise RuntimeError("No generated file_id; inspect skill-response.json")
for index, file_id in enumerate(file_ids, start=1):
from urllib.parse import quote
file_path = "/files/" + quote(file_id, safe="")
metadata = request(file_path)
if metadata.get("downloadable") is not True:
raise RuntimeError("This file cannot be downloaded through Files API")
target = out / f"result-{index}.pptx"
target.write_bytes(request(file_path + "/content", binary=True))
print("Saved:", target)
اختيرت أسماء مثل result-1.pptx لمهمة العرض التقديمي هذه. لا يثبت امتداد الملف محتواه: افتح المستند الذي نزّلته وتحقق من تنسيقه وعدد شرائحه ونصه. لا تعتبر استجابة HTTP 200 وحدها، ولا وجود file_id، دليلًا على نجاح النتيجة.
يطبع البرنامج stop_reason، أي سبب توقف الاستجابة، ويحفظ الاستجابة كاملةً لفحصها. ولا يواصل المحادثة أو يعيد الطلب المدفوع تلقائيًا. لا يعني تنزيل ملف أن المهمة بأكملها اكتملت: افحص الاستجابة المحفوظة والمستند نفسه قبل أن تقرر ما إذا كان يلزم طلب آخر.
في المحاولة الفاشلة، افحص skill-error.json إن وُجد. يسجل حالة HTTP ومعرّف الطلب عند توفره ورسالة مزوّد محدودة الطول بعد حذف مفتاح API المضبوط منها. راجع الرسالة بحثًا عن معلومات خاصة أخرى قبل مشاركتها. قارن أخطاء المصادقة والصلاحيات أو النموذج وحدود الفوترة وتنسيق الطلب بـمرجع الأخطاء الرسمي؛ فليست كل حالات الفشل مبررًا لتوليد مدفوع آخر.
إذا احتوى skill-response.json بالفعل على قيم file_id للملفات المُنشأة وفشل التنزيل فقط، فاحتفظ بالاستجابة وشخّص مرحلة بيانات الملف أو تنزيله باستخدام صلاحية الوصول المصرح بها إلى مساحة العمل نفسها. لا تعِد تشغيل التوليد لتنزيل ناتج موجود. وإذا كانت نتيجة الطلب مجهولة، فاحتفظ بمعرّفه واحسم حالته قبل إرسال توليد آخر. فقط بعد تبرير الحاجة إلى توليد جديد، غيّر سطر الإخراج المحلي إلى مسار غير مستخدم، مثل out = Path("skill-output-attempt-2")، وأبقِ exist_ok=False. يمنع المجلد الجديد الكتابة فوق السابق؛ لكنه لا يمنع تكرار رسوم API.
ما أذونات الملفات المطلوبة؟
تربط Files API الملفات بمساحة عمل، لا بمستخدم فردي لتطبيقك أو بمحادثة. ووفقًا للوثائق، يمكن لأي مفتاح API لديه صلاحية الوصول إلى مساحة العمل الوصول إلى الملفات التي رُفعت إليها. يستخدم المثال المفتاح نفسه للتنزيل والتوليد. لا تقبل مطلقًا file_id من المستخدمين النهائيين أو من مصادر أخرى غير موثوق بها. خزّن هذه المعرّفات على الخادم واحتفظ داخل تطبيقك بربط المستخدمين بملفاتهم.
تحقق من بيانات الملف الوصفية بصورة منفصلة: يجب أن تتضمن downloadable: true. تسمح الوثائق بتنزيل الملفات التي أنشأتها المهارات أو أداة تنفيذ التعليمات البرمجية؛ أما الملفات التي ترفعها أنت فتكون قيمة downloadable فيها false، وتُرجع محاولة تنزيلها الخطأ 400. الوصول إلى مساحة العمل وإمكانية تنزيل ملف معين شرطان منفصلان.
في التطبيقات متعددة المستخدمين، توصي وثائق Files API بمساحة عمل منفصلة لكل عميل لتكون حدًا لعزل الملفات. تتعلق هذه التوصية بالملفات تحديدًا؛ فلا تعممها على جميع الكيانات والأذونات من دون التحقق من API ذات الصلة.
المهارات الجاهزة والمهارات المخصصة
معرّفات المهارات الجاهزة هي pptx وxlsx وdocx وpdf. في مرجع قائمة المهارات، يوصف المصدر custom بأنه خاص بمساحة العمل، بينما يوصف anthropic بأنه مشترك ومتاح للقراءة فقط.
تعني version: "latest" في المثال الأول أحدث إصدار منشور من المهارة. ولإنشاء تكامل قابل لإعادة الإنتاج، ضع في الحسبان أن هذا الاختيار قد يتغير؛ ويتطلب الانتقال إلى إصدار ثابت اختيار إصدار موجود من المهارة التي تستخدمها، بدلًا من اختلاق معرّف من مثال.
القيود والخطوة التالية
لا يغطي المثال سوى إنشاء عرض تقديمي باستخدام مهارة جاهزة وتنزيله. لم يُختبر هنا تحميل المهارات المخصصة أو حذفها أو الوصول إلى خدمات الجهات الخارجية. وتتطلب هذه المهام فحصًا منفصلًا لـ API ذات الصلة.
إذا كانت مهمتك تتعلق بالملفات في واجهة Claude، فهناك دليل منفصل حول كيفية رفع ملف إلى Claude. وللاستدعاءات المباشرة، راجع كيفية حساب استخدام رموز API. أما للعمل في وكيل طرفية، فاقرأ كيفية اختيار مهارات Claude Code؛ إذ تُوصَل هذه المهارات بطريقة مختلفة.
يكفي استخدام مهارة pptx جاهزة للفحص الأول: افحص الاستجابة، ونزّل ملفًا يُسمح بتنزيله، ثم افتحه. أضف المهارات المخصصة وفصل الوصول بين العملاء بعد هذا الفحص.
عندما تكون مستعدًا، تعرّف على Ailoot.
المزيد من التفاصيل
أسئلة شائعة
لماذا لا يكفي file_id لاعتبار العرض التقديمي مكتملًا؟
يثبت المعرّف إرجاع ملف، لكنه لا يثبت صلاحية العرض للاستخدام. افحص بياناته الوصفية بحثًا عن downloadable: true، ونزّله بصلاحية الوصول إلى مساحة العمل، ثم افتحه للتحقق من الصيغة وعدد الشرائح والنص.
هل يمكن تنزيل كل ملف يُرفع إلى Claude Files API؟
لا. يميز الدليل بين الملفات المُنشأة الموسومة downloadable: true والملفات المرفوعة الموسومة downloadable: false. صلاحية مساحة العمل وإذن تنزيل ملف بعينه فحصان مستقلان؛ لا تقبل معرّفات ملفات عشوائية من المستخدمين النهائيين.