طوال عامين كانت أقوى نماذج الترميز مغلقة وباهظة الثمن ويستحيل تشغيلها على أجهزتك الخاصة. GLM-5.2، الذي أطلقته Z.ai (المعروفة سابقًا باسم Zhipu) في 13 يونيو 2026، يكسر هذا النمط. إنه نموذج مفتوح الأوزان من نوع مزيج الخبراء (MoE) مبني لهندسة البرمجيات الوكيلية لا للدردشة، ويأتي بنافذة سياق فعلية قابلة للاستخدام تبلغ مليون رمز، وتُعرَض واجهته البرمجية المستضافة عبر طبقتي توافق في آن واحد — واحدة تحاكي مسار OpenAI /chat/completions وأخرى تحاكي واجهة Anthropic Messages.
تلك الازدواجية هي الجزء المثير للمطورين. فهي تعني أن نموذجًا واحدًا يمكن أن يشغّل خلفية TypeScript عبر OpenAI SDK، و يعمل كبديل مباشر لـ Claude داخل Claude Code، و — لأن الأوزان مرخّصة برخصة MIT ومنشورة على Hugging Face — يعمل بالكامل داخل مركز بياناتك عبر vLLM. وبالنسبة لفرق منطقة الشرق الأوسط وشمال إفريقيا الملتزمة بقواعد الـ INPDP في تونس أو نظام حماية البيانات الشخصية PDPL في السعودية، فإن هذا الخيار الأخير يعني مساعدة ترميز بمستوى الجبهة المتقدمة دون أن يغادر رمز واحد بنيتك التحتية.
يغطّي هذا الدرس كل ذلك: استدعاء GLM-5.2 من TypeScript، والبث، واستدعاء الأدوات، واستبداله داخل Claude Code وCline، وأخيرًا استضافة الأوزان المفتوحة ذاتيًا.
المتطلبات المسبقة
قبل البدء، تأكد من توفر:
- Node.js 20+ ومدير حزم (نستخدم
pnpm، لكنnpmيعمل أيضًا) - إلمام أساسي بـ TypeScript و
async/await - حساب Z.ai بمفتاح واجهة برمجية (اشتراك Coding Plan أو رصيد بالدفع حسب الاستخدام) — سجّل عبر z.ai
- اختياريًا لقسم الاستضافة الذاتية: جهاز Linux مزوّد بمعالج رسومات NVIDIA (أو إمكانية الوصول إليه) وDocker
- اختياريًا: Claude Code و/أو إضافة Cline لـ VS Code مثبّتة
ماذا ستبني
في النهاية سيكون لديك:
- سكربت TypeScript صغير يستدعي GLM-5.2 عبر نقطة النهاية المتوافقة مع OpenAI
- دالة دردشة بالبث وحلقة وكيل تستدعي الأدوات
- Claude Code مُعاد ضبطه لاستخدام GLM-5.2 كخلفية للنموذج
- Cline موجّه إلى النموذج نفسه داخل VS Code
- نقطة نهاية GLM مستضافة ذاتيًا تعمل على vLLM وتتصرف كنظيرتها المستضافة تمامًا
الحيلة التي تجعل العناصر الخمسة ممكنة هي فهم نقطتي نهاية Z.ai، فلنبدأ بهما.
الخطوة 1: فهم نقطتي النهاية
تعرض Z.ai نماذج GLM عبر سطحين برمجيين. اختيار الصحيح منهما لكل أداة هو أهم قرار في هذا الدرس.
| نقطة النهاية | عنوان URL الأساسي | اللهجة | استخدمها لأجل |
|---|---|---|---|
| المتوافقة مع OpenAI | https://api.z.ai/api/paas/v4/ | مسار OpenAI /chat/completions | شيفرتك الخاصة، Cline، Cursor، معظم الـ SDK |
| المتوافقة مع Anthropic | https://api.z.ai/api/anthropic | واجهة Anthropic Messages | Claude Code، حزمة Anthropic SDK |
| خطة الترميز (Anthropic) | https://api.z.ai/api/coding/paas/v4 | واجهة Anthropic Messages | Claude Code على اشتراك Coding Plan |
Z.ai حاليًا هي المزوّد الوحيد بخلاف Anthropic نفسها الذي يقدّم نقطة نهاية متوافقة مع Anthropic. هذا ما يجعل GLM-5.2 بديلاً مباشرًا حقيقيًا لـ Claude Code — دون وكيل ولا مهايئ، فقط عنوان URL أساسي مختلف.
معرّف النموذج هو glm-5.2 في كل مكان، باستثناء واحد سنغطّيه لاحقًا: داخل Claude Code تُلحِق اللاحقة [1m] (glm-5.2[1m]) لفتح نافذة المليون رمز كاملة.
الخطوة 2: إعداد المشروع
أنشئ مشروعًا جديدًا وثبّت OpenAI SDK. رغم أننا نتحدث إلى GLM، فإن نقطة النهاية المتوافقة مع OpenAI تجعل حزمة openai الرسمية أنظف طريقة للدخول.
mkdir glm-quickstart && cd glm-quickstart
pnpm init
pnpm add openai
pnpm add -D typescript tsx @types/node
npx tsc --initاحفظ مفتاحك في متغيّر بيئة بدلاً من تضمينه بصلابة في الشيفرة — وهي قاعدة تنطبق حتى على السكربتات المؤقتة.
# .env (لا ترفعه إلى المستودع أبدًا)
ZAI_API_KEY=your-zai-api-key-hereأضف سطر .env إلى .gitignore، ثم أنشئ src/client.ts الذي يبني عميلاً مضبوطًا مرة واحدة ويصدّره:
// src/client.ts
import OpenAI from "openai";
if (!process.env.ZAI_API_KEY) {
throw new Error("Missing ZAI_API_KEY environment variable");
}
export const glm = new OpenAI({
apiKey: process.env.ZAI_API_KEY,
// عنوان URL الأساسي المتوافق مع OpenAI — لاحظ الشرطة المائلة في النهاية
baseURL: "https://api.z.ai/api/paas/v4/",
});
export const GLM_MODEL = "glm-5.2";لأن العميل ما هو إلا OpenAI SDK موجّه إلى مضيف مختلف، فإن كل دالة تعرفها مسبقًا — chat.completions.create، والبث، واستدعاء الأدوات — تعمل دون تغيير.
الخطوة 3: أول استكمال لديك
أنشئ src/hello.ts:
// src/hello.ts
import "dotenv/config";
import { glm, GLM_MODEL } from "./client";
async function main() {
const completion = await glm.chat.completions.create({
model: GLM_MODEL,
messages: [
{ role: "system", content: "You are a precise senior TypeScript engineer." },
{ role: "user", content: "Write a one-line function that debounces a callback." },
],
});
console.log(completion.choices[0].message.content);
}
main().catch((err) => {
console.error("GLM request failed:", err);
process.exit(1);
});ثبّت dotenv وشغّله:
pnpm add dotenv
pnpm tsx src/hello.tsإذا كان مفتاحك صالحًا، فستظهر لك دالة debounce مطبوعة في الطرفية. لاحظ أن لا شيء في هذه الشيفرة يشير إلى Z.ai سوى عنوان URL الأساسي داخل client.ts — وهذا هو جوهر الطبقة المتوافقة مع OpenAI.
الخطوة 4: استجابات البث
لأي شيء تفاعلي، تريد الرموز فور وصولها بدلاً من انتظار الاستجابة الكاملة. اضبط stream: true وكرّر عبر التدفق غير المتزامن:
// src/stream.ts
import "dotenv/config";
import { glm, GLM_MODEL } from "./client";
async function streamChat(prompt: string) {
const stream = await glm.chat.completions.create({
model: GLM_MODEL,
messages: [{ role: "user", content: prompt }],
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content;
if (delta) process.stdout.write(delta);
}
process.stdout.write("\n");
}
streamChat("Explain the actor model in three sentences.");شكل المقطع (chunk) مطابق لشكل OpenAI، لذا فإن أي شيفرة بث واجهة كتبتها مسبقًا لتطبيقات بأسلوب ChatGPT تعمل دون تغيير.
الخطوة 5: التحكم في جهد الاستدلال
يأتي GLM-5.2 بـ مستويي جهد تفكير قابلين للاختيار. الجهد الأعلى يصرف رموزًا أكثر في الاستدلال قبل الإجابة — وهو يستحق العناء في عمليات إعادة الهيكلة الصعبة وأسئلة المعمارية، ومُهدِر للأسئلة البسيطة. تتحكم فيه عبر المعامل reasoning من خلال تمرير extra_body في الـ SDK (أنواع OpenAI لا تعرفه، لذا نستخدم تحويل النوع):
// src/reasoning.ts
import "dotenv/config";
import { glm, GLM_MODEL } from "./client";
async function deepThink(prompt: string) {
const completion = await glm.chat.completions.create({
model: GLM_MODEL,
messages: [{ role: "user", content: prompt }],
// حقل خاص بـ Z.ai يُمرَّر مباشرة إلى الواجهة البرمجية
// @ts-expect-error reasoning is a Z.ai extension, not in OpenAI types
reasoning: { effort: "high" },
});
return completion.choices[0].message.content;
}
deepThink("Design a retry strategy for a payment webhook that must never double-charge.")
.then(console.log);استخدم الجهد high باعتدال — ففي حلقات الوكيل طويلة الأمد يتراكم. وبالنسبة للاستكمالات الروتينية، احذف المعامل تمامًا ودع النموذج يعتمد وضعه الأسرع.
الخطوة 6: استدعاء الأدوات للوكلاء
سبب بناء GLM-5.2 لـ"هندسة البرمجيات الوكيلية" لا للدردشة هو موثوقيته في استدعاء الأدوات. المخطط هو مصفوفة tools القياسية الخاصة بـ OpenAI، لذا تبدو حلقة الوكيل مألوفة. إليك حلقة بسيطة تمنح النموذج أداة واحدة وتنفّذها:
// src/agent.ts
import "dotenv/config";
import { glm, GLM_MODEL } from "./client";
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions";
const tools = [
{
type: "function" as const,
function: {
name: "get_repo_file_count",
description: "Return how many files live in a given directory of the repo.",
parameters: {
type: "object",
properties: {
path: { type: "string", description: "Directory path, e.g. src/" },
},
required: ["path"],
},
},
},
];
// تنفيذ وهمي — في الواقع ستقرأ نظام الملفات.
function runTool(name: string, args: Record<string, unknown>): string {
if (name === "get_repo_file_count") {
return JSON.stringify({ path: args.path, count: 42 });
}
return JSON.stringify({ error: "unknown tool" });
}
async function agent(userPrompt: string) {
const messages: ChatCompletionMessageParam[] = [
{ role: "user", content: userPrompt },
];
// الدور الأول: النموذج يقرر ما إذا كان سيستدعي أداة.
const first = await glm.chat.completions.create({
model: GLM_MODEL,
messages,
tools,
});
const choice = first.choices[0].message;
messages.push(choice);
// نفّذ أي استدعاءات أدوات وأعد النتائج.
for (const call of choice.tool_calls ?? []) {
const args = JSON.parse(call.function.arguments);
const result = runTool(call.function.name, args);
messages.push({ role: "tool", tool_call_id: call.id, content: result });
}
// الدور الثاني: النموذج يجيب باستخدام مخرجات الأداة.
const second = await glm.chat.completions.create({
model: GLM_MODEL,
messages,
tools,
});
return second.choices[0].message.content;
}
agent("How many files are in the src directory?").then(console.log);في بيئة الإنتاج ستكرّر خطوة تنفيذ الأداة حتى يتوقف النموذج عن طلب الأدوات، وتضيف حارس max_steps، وتسجّل كل استدعاء أداة. لكن النمط الأساسي — اسأل، نفّذ، أعد النتيجة، اسأل مجددًا — هو بالضبط الحلقة التي تشغّل وكلاء الترميز.
الخطوة 7: استخدام GLM-5.2 كخلفية لـ Claude Code
هنا تثبت نقطة النهاية المتوافقة مع Anthropic جدواها. يقرأ Claude Code حفنة من متغيّرات البيئة ليقرر أي واجهة وأي نماذج يستدعي. وجّهها إلى Z.ai ولن يلاحظ Claude Code الفرق.
أضف هذه إلى ملف تعريف الـ shell، أو إلى كتلة env في ~/.claude/settings.json:
export ANTHROPIC_BASE_URL="https://api.z.ai/api/coding/paas/v4"
export ANTHROPIC_API_KEY="your-glm-coding-plan-key"
export ANTHROPIC_DEFAULT_SONNET_MODEL="glm-5.2[1m]"
export ANTHROPIC_DEFAULT_OPUS_MODEL="glm-5.2[1m]"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="glm-4.7"
export CLAUDE_CODE_AUTO_COMPACT_WINDOW=1000000
export API_TIMEOUT_MS=3000000ماذا يفعل كل سطر:
ANTHROPIC_BASE_URLيعيد توجيه كل طلبات Claude Code إلى نقطة نهاية الترميز في Z.ai.ANTHROPIC_DEFAULT_SONNET_MODEL/OPUS_MODELتربط طبقات Claude بـ GLM-5.2. واللاحقة [1m]اصطلاح خاص بـ Claude Code يطلب نسخة سياق المليون رمز.ANTHROPIC_DEFAULT_HAIKU_MODELيوجّه النموذج الخلفي الرخيص (المستخدم للملخّصات والعناوين) إلىglm-4.7الأصغر والأسرع.CLAUDE_CODE_AUTO_COMPACT_WINDOWيخبر Claude Code بألا يضغط المحادثة حتى تقترب من مليون رمز، لتستخدم فعليًا النافذة التي تدفع ثمنها.API_TIMEOUT_MSيرفع مهلة الطلب كي لا تُقطع عمليات الوكيل الطويلة.
احتفظ بمفتاح Anthropic الحقيقي في ملف تعريف shell منفصل إذا كنت ما زلت تستخدم واجهة Claude الأصلية. هذه المتغيّرات عامة على مستوى Claude Code، فضبطها يحوّل كل جلسة إلى GLM حتى تلغي ضبطها.
افتح طرفية جديدة لتُحمَّل المتغيّرات، شغّل claude، واطلب منه القيام بشيء. الآن تأتي الاستجابات من GLM-5.2 — بنحو سُدس تكلفة الرمز مقارنة بنموذج مغلق متقدم.
الخطوة 8: استخدام GLM-5.2 في Cline
يتحدث Cline (وكيل VS Code) لهجة OpenAI، لذا تستخدم هنا نقطة النهاية المتوافقة مع OpenAI. في إعدادات Cline:
- مزوّد الواجهة: OpenAI Compatible
- عنوان URL الأساسي:
https://api.z.ai/api/paas/v4/(أبقِ الشرطة المائلة في النهاية) - مفتاح الواجهة: مفتاح Z.ai الخاص بك
- معرّف النموذج:
glm-5.2(دون لاحقة[1m]هنا — فهي اصطلاح خاص بـ Claude Code فقط) - نافذة السياق:
1000000
ذلك الإعداد الأخير أهم مما يبدو. يستخدم Cline نافذة السياق المضبوطة ليقرر متى يقتطع سجلّ المحادثة. اتركها على قيمة افتراضية صغيرة وستهدر معظم نافذة المليون رمز في GLM-5.2 قبل أن يراها النموذج أصلاً. تعمل الحقول والقيم نفسها مع ضبط النموذج المخصّص في Cursor.
الخطوة 9: استضافة الأوزان المفتوحة ذاتيًا عبر vLLM
الواجهة المستضافة مريحة، لكن الميزة الأبرز للفرق الخاضعة للتنظيم هي أن أوزان GLM-5.2 مرخّصة برخصة MIT ومنشورة على Hugging Face وModelScope. يمكنك تقديمها بنفسك عبر vLLM، الذي يعرض خادمًا متوافقًا مع OpenAI — أي أن ملف client.ts نفسه من الخطوة 2 يعمل مقابل أجهزتك الخاصة بتغيير عنوان URL واحد.
تشغيل بسيط للخادم (على جهاز متعدد المعالجات الرسومية، لأن هذا نموذج MoE كبير):
# ثبّت vLLM في بيئة جديدة
pip install "vllm>=0.8.0"
# قدّم GLM-5.2 بواجهة متوافقة مع OpenAI على المنفذ 8000
vllm serve zai-org/GLM-5.2 \
--served-model-name glm-5.2 \
--tensor-parallel-size 8 \
--max-model-len 200000 \
--host 0.0.0.0 \
--port 8000ثم وجّه عميل TypeScript إلى الخادم المحلي — دون أن يغادر أي مفتاح واجهة شبكتك:
// src/client-selfhosted.ts
import OpenAI from "openai";
export const glm = new OpenAI({
apiKey: "not-needed-locally", // vLLM يتجاهل هذا افتراضيًا
baseURL: "http://localhost:8000/v1",
});
export const GLM_MODEL = "glm-5.2";بالنسبة لفرق الشرق الأوسط وشمال إفريقيا الخاضعة للـ INPDP في تونس أو الـ PDPL في السعودية، الاستضافة الذاتية هي أنظف قصة امتثال: أوزان مفتوحة مع نقطة نهاية vLLM محلية يعني أن الشيفرة المصدرية المملوكة وبيانات العملاء لا تلمس أي واجهة طرف ثالث. ابدأ بطول سياق أصغر (--max-model-len) وارفعه بقدر ما تسمح ذاكرة معالجك الرسومي.
إذا كان النشر الكامل متعدد المعالجات الرسومية بعيد المنال، فابدأ بالواجهة المستضافة للتطوير واحتفظ بمسار الاستضافة الذاتية للأعباء التي تتطلب فعلاً معالجة بيانات داخل المؤسسة.
الخطوة 10: تحقيق أقصى استفادة من سياق المليون رمز
نافذة بمليون رمز تغيّر طريقة كتابتك للموجّهات. فبدلاً من تقليم السياق بعناية، يمكنك لصق وحدة كاملة واختباراتها والوثائق ذات الصلة في طلب واحد. إرشادان عمليان:
- السياق الطويل ليس مجانيًا. حتى مع تحسينات الانتباه المتفرّق في GLM-5.2، فإن مزيدًا من الرموز يعني زمن استجابة وتكلفة أعلى. أرسل المستودع كاملاً حين تحتاج المهمة ذلك فعلاً؛ وأرسل ملفًا واحدًا حين لا تحتاج.
- اللاحقة
[1m]خاصة بـ Claude Code فقط. في شيفرة TypeScript الخاصة بك وفي Cline، تُضبط النافذة عبر الإعدادات (إعداد نافذة السياق)، لا عبر معرّف النموذج. لا تُلحِق[1m]بـglm-5.2في استدعاءات الواجهة — فهو ليس اسم نموذج صالح هناك.
اختبار دمجك
تحقّق من كل طبقة على حدة لتعرف أين تكمن المشكلة:
- طبقة OpenAI:
pnpm tsx src/hello.tsيُرجع استكمالاً ← مفتاحك وعنوان URL الأساسي صحيحان. - البث:
pnpm tsx src/stream.tsيطبع النص تدريجيًا ← البث يعمل. - الأدوات:
pnpm tsx src/agent.tsيُرجع إجابة تشير إلى مخرجات الأداة (العدد 42) ← استدعاء الأدوات يكتمل ذهابًا وإيابًا. - Claude Code: في طرفية جديدة، شغّل
claudeوتحقق من وصول الاستجابات؛ إن أبلغ Claude Code عن خطأ مصادقة، فإنANTHROPIC_API_KEYأو عنوان URL الأساسي خاطئ. - المستضاف ذاتيًا:
curl http://localhost:8000/v1/modelsيسردglm-5.2← خادم vLLM يعمل.
استكشاف الأخطاء وإصلاحها
خطأ 401 غير مصرّح: مفتاح الواجهة مفقود أو غير صحيح التنسيق أو لخطة خاطئة. مفتاح Coding Plan والمفتاح القياسي يُحاسبان بشكل مختلف — تأكد من استخدام المفتاح المطابق لنقطة نهايتك.
Claude Code ما زال يستدعي واجهة Anthropic الحقيقية: متغيّرات البيئة تنطبق فقط على الطرفيات المفتوحة بعد ضبطها. افتح طرفية جديدة، أو تأكد عبر echo $ANTHROPIC_BASE_URL.
الاستجابات تُقتطع مبكرًا في Cline: إعداد نافذة السياق منخفض جدًا. ارفعه إلى 1000000 كي يتوقف Cline عن التخلص من السجل قبل الأوان.
اسم نموذج غير صالح في استدعاء واجهة مباشر: ألحقت [1m] خارج Claude Code. استخدم glm-5.2 فقط في نقطة النهاية المتوافقة مع OpenAI وفي vLLM.
نفاد ذاكرة vLLM عند التشغيل: اخفض --max-model-len، أو زد --tensor-parallel-size إن كان لديك معالجات رسومية أكثر، أو كمّم الأوزان. نموذج MoE كبير يحتاج ذاكرة VRAM كبيرة حتى عندما يكون جزء صغير فقط من المعاملات نشطًا لكل رمز.
الخطوات التالية
- لفّ حلقة الوكيل من الخطوة 6 داخل إطار عمل مناسب — راجع دليلنا حول بناء وكيل ذكاء اصطناعي بـ Vercel AI SDK ووكلاء آمني الأنواع بـ OpenAI Agents SDK، وكلاهما يقبل أي نقطة نهاية متوافقة مع OpenAI.
- أضف قابلية المراقبة لترى استهلاك الرموز وزمن الاستجابة — درسنا حول مراقبة LLM عبر Langfuse يتصل بأي عميل متوافق مع OpenAI.
- قارن GLM-5.2 بنماذج الجبهة المتقدمة مفتوحة الأوزان الأخرى عبر دليل المطور لـ MiniMax M3.
الخلاصة
ابتكار GLM-5.2 الحقيقي ليس مجرد كونه نموذجًا مفتوح الأوزان ينافس الأنظمة المغلقة المتقدمة — بل في مدى قابليته للنقل. نموذج واحد، معروض عبر لهجتي OpenAI وAnthropic، يندمج في شيفرة TypeScript وجلسات Claude Code ومساحة عمل Cline دون أكثر من تغيير عنوان URL الأساسي. ولأن الأوزان مفتوحة، يمكن للشيفرة نفسها أن تعمل مقابل خادم vLLM داخل مركز بياناتك يوم يفرض ذلك متطلب امتثال.
بالنسبة لفرق الشرق الأوسط وشمال إفريقيا خصوصًا، فإن هذا المزيج — جودة ترميز متقدمة، وسُدس التكلفة، ومسار موثوق نحو سيادة كاملة على البيانات داخل المؤسسة — هو ما يجعل GLM-5.2 جديرًا بالدمج في منظومتك اليوم. ابدأ بالواجهة المستضافة للإطلاق سريعًا، واحتفظ بوصفة الاستضافة الذاتية في جعبتك للأعباء التي تتطلبها.