انتقل إلى المحتوى

أدوات جهة العميل

عرض بصيغة Markdown

أداة جهة العميل دالة يشغّلها تطبيقك وينتظرها K-Agent: قراءة سلة العميل في المتصفح، أو فحص حالة جهاز في تطبيق الجوال، أو استدعاء نظام لا يستطيع K-Agent الوصول إليه. يقرر النموذج متى يستدعيها؛ ويشغّلها كودك ويعيد النتيجة؛ ثم يكمل الوكيل رده.

نافذة الطرفية
curl -X PATCH https://api.k-agent.kerneltics.com/v1/agents/store-assistant \
-H "Authorization: Bearer $KAGENT_API_KEY" \
-H "Content-Type: application/json" \
-H "If-Match: $ETAG" \
-d '{
"config": {
"tools": {
"client": [{
"name": "get_cart",
"description": "يعيد المنتجات في سلة العميل مع أسعارها.",
"parameters": { "type": "object", "properties": {}, "additionalProperties": false },
"effect": "read",
"rules": "استدعها قبل ذكر رسوم التوصيل، فهي تعتمد على إجمالي السلة."
}]
}
}
}'

ثم انشر الوكيل. ملاحظات:

  • name يطابق ^[a-z][a-z0-9_]{0,47}$ ويجب ألا يتعارض مع أدوات الوكيل الأخرى.
  • parameters مخطط JSON؛ ويُتحقق من المعاملات بصرامة قبل أن يراها تطبيقك.
  • effect افتراضيًا action. اجعله read للأدوات التي تستعلم فقط، فتعمل أيضًا للمستخدمين المجهولين وفي طلبات السؤال الواحد دون allow_actions.

2. يتوقف التشغيل مؤقتًا بحالة requires_action

رابط القسم «2. يتوقف التشغيل مؤقتًا بحالة requires_action»

حين يستدعي النموذج الأداة يتوقف التشغيل وينتظرك:

{
"id": "run_01k6rz7d9f1h3k5n7q9s1v3x5z",
"object": "run",
"status": "requires_action",
"outcome": null,
"required_action": {
"type": "submit_tool_outputs",
"tool_calls": [{ "call_id": "call_8f2k1", "name": "get_cart", "arguments": {} }],
"expires_at": 1791272520
}
}
  • دون بث، يعيد POST …/messages (أو ask) هذا التشغيل بالحالة 200.
  • مع البث، ينتهي البث بحدث run.requires_action يحمل run فيه required_action.
  • التشغيل المتوقف يحتفظ بدور الجلسة: مع queue تنتظر الرسائل الجديدة خلفه، ومع reject تحصل على 409 session_busy.

3. شغّل الأداة وأرسل النتائج

رابط القسم «3. شغّل الأداة وأرسل النتائج»

أجب عن كل استدعاء في tool_calls، خلال 10 دقائق:

const BASE = 'https://api.k-agent.kerneltics.com/v1';
const headers = { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' };
// Your implementations, keyed by tool name.
const clientTools = {
get_cart: async () => ({ items: [{ name: 'صندوق بخور', qty: 1, price_sar: 95 }], subtotal_sar: 95 }),
};
async function send(session, input) {
let res = await fetch(`${BASE}/sessions/${encodeURIComponent(session)}/messages`, {
method: 'POST',
headers,
body: JSON.stringify({ input, client_message_id: crypto.randomUUID() }),
});
let { run } = await res.json();
// A run can pause more than once: keep answering until it finishes.
while (run?.status === 'requires_action') {
const tool_outputs = await Promise.all(
run.required_action.tool_calls.map(async (call) => {
try {
const output = await clientTools[call.name](call.arguments);
return { call_id: call.call_id, output, is_error: false };
} catch (err) {
return { call_id: call.call_id, output: { message: String(err) }, is_error: true };
}
}),
);
res = await fetch(`${BASE}/runs/${run.id}/submit_tool_outputs`, {
method: 'POST',
headers,
body: JSON.stringify({ tool_outputs }),
});
run = await res.json(); // submit_tool_outputs returns the run
}
return run; // completed: read run.output_text and run.outcome
}
  • output أي قيمة JSON. اجعل is_error: true حين تفشل الأداة، ليتعامل النموذج مع الموقف بلباقة (مثل سؤال العميل أو التحويل لموظف).
  • يقبل submit_tool_outputs الحقلين stream: true وwait_seconds مثل أي طلب تشغيل آخر، ويعيد التشغيل.
  • النتائج الناقصة تعيد 422 tool_outputs_incomplete. والإرسال إلى تشغيل لا ينتظر يعيد 409 run_not_requires_action.
  • إذا لم يصل شيء خلال 10 دقائق ينتهي التشغيل failed بالرمز tool_outputs_expired (دون رد طوارئ ودون تحويل). ورسالة العميل التالية تبدأ تشغيلًا جديدًا.

تستطيع رموز العميل استدعاء submit_tool_outputs لتشغيلات جلساتها، فيستطيع تطبيق الويب الإجابة عن أدوات جهة العميل مباشرة في المتصفح — مثل قراءة سلة لا توجد إلا هناك. أما خطوات التشغيل (/steps) فتبقى خاصة بخادمك.

  • لا تُعرض أدوات جهة العميل في طلبات store: false.
  • مع الواجهة المتوافقة مع OpenAI تعرض الطلبات بلا حالة أدوات جهة العميل استدعاءاتٍ عادية في tool_calls مع finish_reason: "tool_calls"؛ وينتهي التشغيل بالنتيجة client_tool_calls، ويكون طلبك التالي تشغيلًا جديدًا.
  • requires_action حالة وليست نتيجة أبدًا: التشغيل المتوقف ينتهي لاحقًا دائمًا بـ completed أو failed أو cancelled أو superseded.