مقدمة
Mastra هو إطار عمل TypeScript المخصص لبناء وكلاء الذكاء الاصطناعي وسير العمل وخطوط RAG. أطلقه فريق Gatsby.js وحظي بدعم Y Combinator (دفعة W25، بتمويل 13 مليون دولار)، وحقق أكثر من 22 ألف نجمة على GitHub وأكثر من 300 ألف تنزيل أسبوعي عبر npm بحلول إصدار 1.0 في يناير 2026. وعلى خلاف المكتبات التي تعتمد Python أساساً كـ LangChain، صُمِّم Mastra من الصفر لبيئة TypeScript/JavaScript.
في هذا الدليل ستبني وكيل دعم العملاء القادر على:
- البحث في قاعدة المعرفة عبر RAG
- استدعاء واجهات API خارجية كأدوات
- الاحتفاظ بذاكرة المحادثات عبر الجلسات
- توجيه المهام المعقدة عبر سير عمل متعدد الخطوات
المتطلبات المسبقة
قبل البدء، تأكد من توفّر ما يلي:
- Node.js 20 أو أحدث (تحقق بالأمر
node -v) - مدير حزم: npm أو pnpm أو yarn أو bun
- مفتاح API لنموذج لغوي (OpenAI أو Anthropic أو أي من أكثر من 94 مزوداً مدعوماً)
- معرفة أساسية بـ TypeScript
ما ستبنيه
وكيل دعم عملاء متكامل باسم SupportBot يعالج أسئلة المستخدمين، ويستعلم من قاعدة معرفة المنتج عبر RAG، ويُصعِّد التذاكر المعقدة عبر سير عمل منظم، ويتذكر المحادثات السابقة.
الخطوة 1: إعداد المشروع
استخدم واجهة سطر أوامر Mastra لإنشاء مشروع جديد:
npm create mastra@latestسيطلب منك المعالج:
- اسم المشروع —
support-agent - المزود — اختر OpenAI أو Anthropic
- النموذج الافتراضي —
gpt-4oأوclaude-sonnet-4-6 - المكونات — اختر Agents وTools وWorkflows وMemory
انتقل إلى مجلد المشروع وثبِّت التبعيات:
cd support-agent
npm installسيبدو هيكل مشروعك كالتالي:
support-agent/
├── src/
│ └── mastra/
│ ├── agents/
│ │ └── support-agent.ts
│ ├── tools/
│ │ └── ticket-tool.ts
│ ├── workflows/
│ │ └── escalation-workflow.ts
│ └── index.ts
├── .env
├── package.json
└── tsconfig.json
أضف مفتاح API إلى ملف .env:
OPENAI_API_KEY=sk-...
# أو
ANTHROPIC_API_KEY=sk-ant-...الخطوة 2: إنشاء أول وكيل
افتح src/mastra/agents/support-agent.ts وعرِّف الوكيل:
import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";
import { ticketTool, knowledgeBaseTool } from "../tools/ticket-tool";
export const supportAgent = new Agent({
name: "SupportBot",
instructions: `أنت وكيل دعم عملاء متعاون لمنصة نقطة.
مسؤولياتك:
- الإجابة على أسئلة المنصة باستخدام أداة قاعدة المعرفة
- إنشاء تذاكر دعم للمشكلات غير المحلولة
- الحرص على أن تكون إجاباتك متعاطفة وموجزة ومركّزة على الحل
- التصعيد إلى إنسان في حال كانت المشكلة حرجة أو تقنية`,
model: openai("gpt-4o"),
tools: {
ticketTool,
knowledgeBaseTool,
},
});الخطوة 3: بناء أدوات مخصصة مع التحقق من البيانات بـ Zod
تمنح الأدواتُ الوكيلَ قدرات حقيقية. تستخدم كل أداة Zod للتحقق الآمن من المدخلات والمخرجات.
أنشئ الملف src/mastra/tools/ticket-tool.ts:
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
// أداة للبحث في قاعدة المعرفة
export const knowledgeBaseTool = createTool({
id: "search-knowledge-base",
description: "ابحث في الأسئلة الشائعة والوثائق للإجابة على أسئلة المستخدم",
inputSchema: z.object({
query: z.string().describe("سؤال المستخدم للبحث عنه"),
limit: z.number().optional().default(3).describe("عدد النتائج المطلوبة"),
}),
outputSchema: z.object({
results: z.array(
z.object({
title: z.string(),
content: z.string(),
relevance: z.number(),
})
),
}),
execute: async ({ context }) => {
const { query, limit } = context;
const results = await searchVectorDB(query, limit);
return { results };
},
});
// أداة لإنشاء تذكرة دعم
export const ticketTool = createTool({
id: "create-ticket",
description: "أنشئ تذكرة دعم عند عدم إمكانية حل المشكلة فوراً",
inputSchema: z.object({
title: z.string().describe("ملخص قصير للمشكلة"),
description: z.string().describe("وصف تفصيلي للمشكلة"),
priority: z.enum(["low", "medium", "high", "critical"]).describe("مستوى أولوية المشكلة"),
userEmail: z.string().email().describe("عنوان بريد العميل"),
}),
outputSchema: z.object({
ticketId: z.string(),
status: z.string(),
estimatedResolution: z.string(),
}),
execute: async ({ context }) => {
const { title, description, priority, userEmail } = context;
const ticket = await createSupportTicket({ title, description, priority, userEmail });
return {
ticketId: ticket.id,
status: "created",
estimatedResolution: priority === "critical" ? "ساعتان" : "24 ساعة",
};
},
});
async function searchVectorDB(query: string, limit: number) {
return [{ title: "الأسئلة الشائعة", content: "إجابة نموذجية لـ: " + query, relevance: 0.9 }];
}
async function createSupportTicket(data: object) {
return { id: "TKT-" + Math.random().toString(36).substr(2, 8).toUpperCase() };
}الخطوة 4: إضافة ذاكرة دائمة
تتيح ذاكرة Mastra للوكلاء تذكر المحادثات السابقة عبر الجلسات. اضبطها مع نظام تخزين:
import { Agent } from "@mastra/core/agent";
import { Memory } from "@mastra/memory";
import { LibSQLStore } from "@mastra/memory/storage/libsql";
import { openai } from "@ai-sdk/openai";
const memory = new Memory({
storage: new LibSQLStore({
url: "file:./support-memory.db",
// للإنتاج: url: process.env.DATABASE_URL
}),
options: {
lastMessages: 20,
semanticRecall: {
topK: 5,
messageRange: 2,
},
},
});
export const supportAgent = new Agent({
name: "SupportBot",
instructions: "...",
model: openai("gpt-4o"),
memory,
tools: { ticketTool, knowledgeBaseTool },
});استدعِ الوكيل مع معرّف جلسة للحفاظ على استمرارية المحادثة:
const response = await supportAgent.generate(
"فشلت عملية الدفع لكن تم خصم المبلغ من حسابي",
{
resourceId: "user-123", // يُعرِّف المستخدم
threadId: "session-456", // يُعرِّف جلسة المحادثة
}
);
console.log(response.text);الاستدعاءات التالية بنفس threadId ستتاح لها كامل سجل المحادثة.
الخطوة 5: بناء سير عمل تصعيد متعدد الخطوات
للمهام المعقدة التي تحتاج مساراً تنفيذياً محدداً، استخدم محرك سير العمل في Mastra:
import { createWorkflow, createStep } from "@mastra/core/workflows";
import { z } from "zod";
// الخطوة 1: تحليل التذكرة
const analyzeTicketStep = createStep({
id: "analyze-ticket",
description: "تصنيف أولوية التذكرة وفئتها",
inputSchema: z.object({
userMessage: z.string(),
userEmail: z.string().email(),
}),
outputSchema: z.object({
priority: z.enum(["low", "medium", "high", "critical"]),
category: z.string(),
needsEscalation: z.boolean(),
}),
execute: async ({ inputData }) => {
const classification = await classifyWithLLM(inputData.userMessage);
return classification;
},
});
// الخطوة 2: توجيه التذكرة
const routeTicketStep = createStep({
id: "route-ticket",
description: "توجيه التذكرة إلى الفريق المناسب",
inputSchema: z.object({
priority: z.enum(["low", "medium", "high", "critical"]),
category: z.string(),
needsEscalation: z.boolean(),
}),
outputSchema: z.object({
assignedTeam: z.string(),
ticketId: z.string(),
}),
execute: async ({ inputData }) => {
const team = inputData.needsEscalation
? "tier-2-engineering"
: "tier-1-support";
const ticketId = await assignToTeam(team, inputData);
return { assignedTeam: team, ticketId };
},
});
// الخطوة 3: إشعار المستخدم
const notifyUserStep = createStep({
id: "notify-user",
description: "إرسال بريد تأكيد للمستخدم",
inputSchema: z.object({
assignedTeam: z.string(),
ticketId: z.string(),
}),
outputSchema: z.object({
notificationSent: z.boolean(),
}),
execute: async ({ inputData }) => {
await sendConfirmationEmail(inputData.ticketId, inputData.assignedTeam);
return { notificationSent: true };
},
});
// تجميع سير العمل
export const escalationWorkflow = createWorkflow({
name: "ticket-escalation",
triggerSchema: z.object({
userMessage: z.string(),
userEmail: z.string().email(),
}),
})
.then(analyzeTicketStep)
.then(routeTicketStep)
.then(notifyUserStep)
.commit();
async function classifyWithLLM(message: string) {
return { priority: "high" as const, category: "billing", needsEscalation: true };
}
async function assignToTeam(team: string, data: object) {
return "TKT-" + Date.now();
}
async function sendConfirmationEmail(ticketId: string, team: string) {
console.log(`تم إرسال البريد لـ ${ticketId} إلى ${team}`);
}الخطوة 6: تسجيل كل المكونات في Mastra
اربط جميع المكونات في src/mastra/index.ts:
import { Mastra } from "@mastra/core";
import { supportAgent } from "./agents/support-agent";
import { escalationWorkflow } from "./workflows/escalation-workflow";
export const mastra = new Mastra({
agents: { supportAgent },
workflows: { escalationWorkflow },
logger: {
type: "CONSOLE",
level: "INFO",
},
});الخطوة 7: الاختبار باستخدام Mastra Studio
شغِّل خادم التطوير وافتح Mastra Studio:
npm run devافتح http://localhost:4111 في متصفحك. يوفر لك Mastra Studio:
- واجهة دردشة الوكيل — اختبر وكيلك برسائل حقيقية
- مُصوِّر سير العمل — اعرض خطوات سير العمل كمخطط انسيابي
- مفتش الأدوات — تابع استدعاءات الأدوات والاستجابات بشكل مباشر
- متصفح الذاكرة — افحص تاريخ المحادثات المخزن
جرِّب الوكيل بإرسال: "فشلت عملية الدفع لكن تم خصم المبلغ من حسابي. بريدي الإلكتروني test@example.com"
ستشاهد الوكيل:
- يبحث في قاعدة المعرفة عن مشكلات الدفع
- ينشئ تذكرة دعم تلقائياً
- يُرجع ردًا متعاطفاً يتضمن رقم التذكرة
الخطوة 8: النشر للإنتاج
تطبيقات Mastra هي خوادم Node.js قياسية. انشرها على أي سحابة:
الخيار أ: Docker
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 4111
CMD ["npm", "start"]الخيار ب: Vercel (موصى به لتكامل Next.js)
npm install @mastra/vercel-functions
npx vercel deployالخيار ج: Fly.io
fly launch --name support-agent
fly deployضبط متغيرات البيئة على منصة النشر:
# Fly.io
fly secrets set OPENAI_API_KEY=sk-...
# Vercel
vercel env add OPENAI_API_KEYاختبار التطبيق
اكتب اختبارات تكامل باستخدام @mastra/testing:
import { createTestRun } from "@mastra/testing";
import { mastra } from "./src/mastra";
const testRun = createTestRun({ mastra });
test("ينشئ الوكيل تذكرة لمشكلات الفوترة", async () => {
const result = await testRun.agent("supportAgent").generate(
"تم خصم مبلغ الاشتراك مرتين من حسابي",
{ resourceId: "test-user", threadId: "test-thread" }
);
expect(result.toolCalls).toContainEqual(
expect.objectContaining({ toolName: "create-ticket" })
);
expect(result.text).toContain("ticket");
});استكشاف الأخطاء وإصلاحها
الوكيل لا يستدعي الأدوات: تأكد من أن وصف الأداة مفصّل بما يكفي. يقرر النموذج اللغوي استدعاء الأداة بناءً على حقل description — اجعله محدداً وموجهاً نحو الفعل.
الذاكرة لا تُحفظ: تحقق من أن resourceId وthreadId متسقان بين الاستدعاءات. استخدام معرّفات مختلفة يُنشئ خيوط ذاكرة منفصلة.
أخطاء التحقق Zod: عندما لا يتطابق outputSchema للأداة مع ما يُرجعه execute، يرمي Mastra خطأ تحقق. استخدم z.infer لإبقاء الأنواع متوافقة.
Studio لا يُحمَّل: تأكد من أن المنفذ 4111 متاح. استخدم MASTRA_PORT=4112 npm run dev لتغييره.
الخطوات التالية
بعد امتلاك وكيل يعمل، فكّر في:
- البحث المتجه مع Pinecone — ربط قاعدة بيانات متجهات حقيقية لـ RAG
- المهام في الخلفية مع Inngest — تشغيل مهام الوكيل طويلة المدى بشكل غير متزامن
- الوكلاء ذوو الحالة مع LangGraph — مقارنة نماذج سير العمل
- استكشاف وثائق Mastra للتقييم والمراقبة وتنسيق الوكلاء المتعددة
الخلاصة
يُحضر Mastra منظومة TypeScript الكاملة إلى تطوير وكلاء الذكاء الاصطناعي — السلامة النوعية والتحقق بـ Zod والأدوات المألوفة والتكامل السلس مع Next.js وNode.js. بنهاية هذا الدليل أصبحت قد بنيت وكيل دعم جاهزاً للإنتاج مزوداً بأدوات وذاكرة دائمة وسير عمل تصعيد منظم. هذا النمط قابل للتوسع من روبوتات الدردشة البسيطة إلى أنظمة الوكلاء المتعددة المستقلة التي تخدم آلاف المستخدمين.