جميع المقالات
وكلاء الذكاء الاصطناعيChat SDKدليل عملي

كيف تبني وكيل ذكاء اصطناعي متعدد المنصات باستخدام Vercel Chat SDK

8 min readSoftware Savants

معظم الفرق التي تبني وكلاء ذكاء اصطناعي تصطدم بنفس الجدار: الوكيل يعمل بشكل ممتاز في مكان واحد، لكن لحظة ما تريده على Slack وWhatsApp وTelegram، تجد نفسك تدير ثلاث قواعد كود منفصلة بثلاث واجهات API مختلفة، وثلاثة أنظمة مصادقة، وثلاث مجموعات من مشاكل التنسيق.

أطلقت Vercel مؤخراً Chat SDK — مكتبة TypeScript موحدة تحل هذه المشكلة بالضبط. تكتب منطق البوت مرة واحدة، تضيف محولات المنصات، وتنشر في كل مكان من قاعدة كود واحدة.

دمجناها مع Vercel AI SDK لبناء قالب مفتوح المصدر يجعل وكيل ذكاء اصطناعي متعدد المنصات يعمل في أقل من 30 دقيقة.

إليك كيف يعمل، وكيف تبني واحداً خاصاً بك.

ما الذي نبنيه

وكيل ذكاء اصطناعي واحد يقوم بالتالي:

  • يرد على الرسائل على Slack وWhatsApp وTelegram
  • يبث ردود الذكاء الاصطناعي في الوقت الفعلي بتنسيق أصلي لكل منصة
  • يحافظ على حالة المحادثة عبر المنصات باستخدام Redis
  • يعمل على نشر Next.js واحد

بنهاية هذا الدليل، سيكون لديك وكيل يعمل يمكنك نسخه وتخصيصه ونشره.

الهندسة المعمارية

المكونات على ثلاث طبقات:

الرسائل الواردة (Slack, WhatsApp, Telegram)
        ↓
   Chat SDK (معالجة موحدة للرسائل + الحالة)
        ↓
   AI SDK + LLM (الاستدلال + الردود)
        ↓
الرسائل الصادرة (تنسيق أصلي لكل منصة)

Chat SDK يتعامل مع البنية التحتية للرسائل — استقبال webhooks من كل منصة، إدارة المحادثات والاشتراكات، وإرسال الردود بالتنسيق المناسب.

AI SDK يتعامل مع طبقة الذكاء الاصطناعي — بث الردود، إدارة استدعاءات الأدوات، والتعامل مع المحادثات متعددة الأدوار.

هذا الفصل مهم. منطق الوكيل يعيش في مكان واحد. مشاكل المنصات تبقى على الأطراف.

المتطلبات الأساسية

  • Node.js
  • مفتاح API لنموذج لغوي (نستخدم Anthropic في هذا الدليل — AI SDK يدعم أكثر من 50 مزود إذا كنت تفضل نموذجاً مختلفاً)
  • نسخة Redis (لحالة المحادثة)
  • بيانات اعتماد المنصة لأي منصة تريد النشر عليها (سنغطي Slack وWhatsApp وTelegram)

الخطوة 1: إعداد المشروع

npx create-next-app@latest my-agent --typescript --app
cd my-agent

تثبيت التبعيات:

pnpm add ai @ai-sdk/anthropic chat @chat-adapter/slack @chat-adapter/telegram @chat-adapter/whatsapp @chat-adapter/state-redis

إعداد متغيرات البيئة. كل محول يكتشف بيانات الاعتماد تلقائياً من متغيرات البيئة:

# .env.local
 
# AI
ANTHROPIC_API_KEY=sk-ant-...
 
# State (Redis)
REDIS_URL=redis://...
 
# Slack
SLACK_BOT_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=...
 
# Telegram
TELEGRAM_BOT_TOKEN=...
 
# WhatsApp
WHATSAPP_ACCESS_TOKEN=...
WHATSAPP_VERIFY_TOKEN=...
WHATSAPP_PHONE_NUMBER_ID=...

الخطوة 2: تهيئة Chat SDK

أنشئ lib/bot.ts — هذا هو جوهر الوكيل:

import { Chat } from "chat";
import { createSlackAdapter } from "@chat-adapter/slack";
import { createTelegramAdapter } from "@chat-adapter/telegram";
import { createWhatsAppAdapter } from "@chat-adapter/whatsapp";
import { createRedisState } from "@chat-adapter/state-redis";
 
export const bot = new Chat({
  userName: "my-agent",
  adapters: {
    slack: createSlackAdapter(),
    telegram: createTelegramAdapter(),
    whatsapp: createWhatsAppAdapter(),
  },
  state: createRedisState(),
});

لاحظ أنه لا يتم تمرير كائنات تكوين للمحولات — فهي تكتشف بيانات الاعتماد تلقائياً من متغيرات البيئة التي أعددناها أعلاه. مرر قيماً صريحة فقط عندما تحتاج تجاوز الإعدادات الافتراضية.

الخطوة 3: تسجيل معالجات الأحداث

لا نزال في lib/bot.ts، أضف المعالجات التي تنطلق عند وصول الرسائل:

import { streamText } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
 
const SYSTEM_PROMPT = `You are a helpful assistant deployed across multiple
communication platforms. Be concise and direct. When answering questions,
focus on being actionable rather than verbose.`;
 
// عندما يذكر شخص الوكيل في محادثة جديدة
bot.onNewMention(async (thread, message) => {
  await thread.subscribe();
  await thread.startTyping();
 
  const result = streamText({
    model: anthropic("claude-sonnet-4-6"),
    system: SYSTEM_PROMPT,
    messages: [{ role: "user", content: message.text }],
  });
 
  // نشر البث مباشرة — Chat SDK يتعامل مع
  // التحديثات المجزأة والتنسيق الأصلي لكل منصة
  await thread.post(result.fullStream);
});
 
// عندما يرد شخص في محادثة يراقبها الوكيل
bot.onSubscribedMessage(async (thread, message) => {
  if (message.author.isBot) return;
 
  await thread.startTyping();
 
  // بناء سجل المحادثة من المحادثة
  const history: Array<{ role: "user" | "assistant"; content: string }> = [];
  for await (const msg of thread.messages) {
    history.push({
      role: msg.author.isBot ? "assistant" : "user",
      content: msg.text,
    });
  }
 
  const result = streamText({
    model: anthropic("claude-sonnet-4-6"),
    system: SYSTEM_PROMPT,
    messages: history,
  });
 
  await thread.post(result.fullStream);
});

الشيء الرئيسي هنا: thread.post() يقبل بث AI SDK مباشرة. Chat SDK يتعامل مع تجزئة الرد المبثوث إلى تحديثات فورية على كل منصة. في Slack، تتحرر الرسالة في مكانها مع وصول الرموز. في Telegram، يتم تعديل الرسالة تدريجياً. في WhatsApp، ينتظر الرد الكامل لأن WhatsApp لا يدعم تعديل الرسائل.

نفس معالجات onNewMention وonSubscribedMessage تنطلق بغض النظر عما إذا جاءت الرسالة من Slack أو WhatsApp أو Telegram. Chat SDK يجرد المنصة بعيداً.

الخطوة 4: ربط مسارات Webhook

كل منصة ترسل الأحداث لتطبيقك عبر webhooks. Chat SDK يوفر معالجات webhook مكتوبة بأمان حسب اسم المحول:

// app/api/slack/route.ts
import { bot } from "@/lib/bot";
 
export async function POST(request: Request) {
  return bot.webhooks.slack(request);
}
// app/api/telegram/route.ts
import { bot } from "@/lib/bot";
 
export async function POST(request: Request) {
  return bot.webhooks.telegram(request);
}
// app/api/whatsapp/route.ts
import { bot } from "@/lib/bot";
 
export async function GET(request: Request) {
  // التحقق من webhook WhatsApp
  return bot.webhooks.whatsapp(request);
}
 
export async function POST(request: Request) {
  return bot.webhooks.whatsapp(request);
}

الخطوة 5: إضافة تنسيق حسب المنصة

هنا تصبح الوكلاء متعددو المنصات مثيرة للاهتمام. كتلة كود تبدو رائعة على Slack لكنها تتكسر على WhatsApp. رد طويل يعمل في محادثة مترابطة لكنه يغرق دردشة Telegram أو WhatsApp.

يمكنك تعديل موجه النظام حسب المنصة باستخدام محول المحادثة:

const platformInstructions: Record<string, string> = {
  slack:
    "Use Slack markdown: *bold*, `code`, ```code blocks```. Use threaded replies naturally.",
  telegram:
    "Use Telegram markdown: **bold**, `code`, ```code blocks```. Keep responses focused and under 4096 characters.",
  whatsapp:
    "Keep responses short and concise. No code blocks. Use *bold* sparingly. Break long responses into short paragraphs.",
};
 
bot.onNewMention(async (thread, message) => {
  await thread.subscribe();
  await thread.startTyping();
 
  const adapterName = thread.adapter.name;
 
  const result = streamText({
    model: anthropic("claude-sonnet-4-6"),
    system: `${SYSTEM_PROMPT}\n\nFormatting: ${platformInstructions[adapterName] ?? "Be concise."}`,
    messages: [{ role: "user", content: message.text }],
  });
 
  await thread.post(result.fullStream);
});

أعطِ النموذج تعليمات تنسيق خاصة بالمنصة وسيكيّف مخرجاته وفقاً لذلك. لا حاجة لمعالجة لاحقة.

الخطوة 6: إضافة أدوات (اختياري لكن قوي)

القوة الحقيقية لوكيل الذكاء الاصطناعي تأتي من استخدام الأدوات. إليك مثال يمنح وكيلك وصولاً لأهم القصص على Hacker News — بدون مفتاح API:

import { streamText, tool, stepCountIs } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";
 
const tools = {
  getTopStories: tool({
    description: "Get the current top stories from Hacker News",
    inputSchema: z.object({
      count: z
        .number()
        .min(1)
        .max(10)
        .default(5)
        .describe("Number of stories to return"),
    }),
    execute: async ({ count }) => {
      const idsRes = await fetch(
        "https://hacker-news.firebaseio.com/v0/topstories.json",
      );
      const ids = (await idsRes.json()).slice(0, count);
 
      const stories = await Promise.all(
        ids.map(async (id: number) => {
          const res = await fetch(
            `https://hacker-news.firebaseio.com/v0/item/${id}.json`,
          );
          const story = await res.json();
          return {
            title: story.title,
            url: story.url,
            score: story.score,
            by: story.by,
          };
        }),
      );
 
      return { stories };
    },
  }),
};
 
bot.onNewMention(async (thread, message) => {
  await thread.subscribe();
  await thread.startTyping();
 
  const result = streamText({
    model: anthropic("claude-sonnet-4-6"),
    system: SYSTEM_PROMPT,
    messages: [{ role: "user", content: message.text }],
    tools,
    stopWhen: stepCountIs(3),
  });
 
  // fullStream يتعامل مع خطوات استدعاء الأدوات الوسيطة تلقائياً
  await thread.post(result.fullStream);
});

لا مفتاح API، لا إعداد — فقط اسأل "ما الذي يتصدر Hacker News؟" من أي منصة والوكيل يجلب البيانات الحية. في الإنتاج، ستضيف أدوات لواجهات API الخاصة بك — البحث في CRM، تتبع الطلبات، استعلامات قاعدة البيانات — باستخدام نفس النمط.

الخطوة 7: النشر

هذا تطبيق Next.js عادي — انشره في أي مكان تستضيف فيه خادم Node.js: Vercel أو Railway أو Fly.io أو AWS أو VPS، إلخ. المتطلب الوحيد هو عنوان URL متاح للعامة لاستقبال webhooks.

pnpm build

بعد النشر، اضبط عناوين webhook في كل منصة:

هذا كل شيء. قاعدة كود واحدة، ثلاث منصات، نشر واحد.

إلى أين بعد ذلك

لديك الآن وكيل يعمل على ثلاث منصات. إليك الخطوات التالية الأكثر شيوعاً:

أضف قاعدة معرفة. حالياً الوكيل يعرف فقط ما في موجه النظام. اربطه بمستنداتك أو مركز المساعدة أو الويكي الداخلي باستخدام RAG (التوليد المعزز بالاسترجاع) ليتمكن من الإجابة على الأسئلة بناءً على محتواك الفعلي. نظام الأدوات في AI SDK يجعل هذا سهلاً — أنشئ أداة استرجاع تبحث في مخزن المتجهات وتعيد السياق للنموذج.

اربطه بأنظمتك. مثال الأداة في الخطوة 6 هو نقطة البداية. في الإنتاج، ستضيف أدوات لـ CRM وقاعدة البيانات ونظام التذاكر أو أي شيء يحتاج المستخدمون التفاعل معه عبر الوكيل. كل أداة هي مجرد دالة بمخطط — النموذج يقرر متى يستدعيها.

أضف المزيد من المنصات. Chat SDK لديه محولات لـ Teams وGoogle Chat وGitHub وLinear والمزيد. إضافة منصة جديدة هي import واحد وسطر محول واحد — بدون تغييرات في منطق الوكيل.

اضبط المراقبة. تابع أي المنصات تحصل على أكثر استخدام، وما الأسئلة التي لا يستطيع الوكيل الإجابة عليها، وأين يتعثر. هذه البيانات تخبرك بما يجب تحسينه. AI SDK يدعم OpenTelemetry لتتبع استدعاءات النموذج، ومحول الحالة لديك يحتوي بالفعل على سجل المحادثات.

احصل على القالب

القالب الكامل مفتوح المصدر ومتاح على GitHub:

github.com/SoftwareSavants/multi-platform-agent-starter

انسخه، خصصه، وانشره.

إذا وصلت لحدود ما يمكن للقالب تقديمه — تكاملات مخصصة، ضبط السلوك لكل قناة، لوحات مراقبة، تجهيز الإنتاج — يمكننا المساعدة.