بناء وكلاء ذكاء اصطناعي متقدمين باستخدام LangGraph.js و TypeScript

أغلب روبوتات الدردشة الذكية لا تملك ذاكرة — تعالج الرسالة وتنسى. لكن التطبيقات الحقيقية تحتاج وكلاء قادرين على التذكر والتحليل واتخاذ القرارات بناءً على السياق.
LangGraph.js يحل هذه المشكلة. يوفر لك إطار عمل لبناء وكلاء الذكاء الاصطناعي على شكل رسم بياني موجَّه (Directed Graph) — كل عقدة تمثل خطوة (استدعاء نموذج لغوي، استخدام أداة، اتخاذ قرار) والحواف تحدد مسار التنفيذ. الحالة (State) تنتقل عبر الرسم البياني وتتراكم فيها المعلومات في كل خطوة.
في هذا الدرس، ستبني وكيل ذكاء اصطناعي متكامل قادر على:
- البحث في الويب عن معلومات
- إجراء عمليات حسابية
- تحديد الأدوات المناسبة حسب سؤال المستخدم
- الاحتفاظ بذاكرة المحادثة عبر جولات متعددة
- معالجة الأخطاء بشكل سلس
في نهاية الدرس، سيكون لديك نمط وكيل جاهز للإنتاج يمكنك توسيعه لأي حالة استخدام.
المتطلبات
قبل البدء، تأكد من توفر:
- Node.js 20+ (تحقق بـ
node --version) - معرفة أساسية بـ TypeScript (الأنواع، الواجهات، async/await)
- مفتاح API من OpenAI (أو أي مزود آخر — سنعرض البدائل)
- فهم أساسي لماهية النماذج اللغوية الكبيرة (LLMs) والتوجيهات (Prompts)
- محرر أكواد (يُفضل VS Code)
ما هو LangGraph.js؟
LangGraph.js هو النسخة JavaScript/TypeScript من مكتبة LangGraph — التي بناها فريق LangChain لإنشاء سير عمل وكلاء ذكاء اصطناعي متعدد الخطوات مع حفظ الحالة.
فكّر فيه كـ آلة حالات (State Machine) للذكاء الاصطناعي:
| المفهوم | المعنى |
|---|---|
| الحالة (State) | البيانات التي تتدفق عبر الوكيل (رسائل، نتائج، قرارات) |
| العقدة (Node) | دالة تستقبل الحالة، تنفذ عملية (استدعاء LLM، تشغيل أداة)، وتُرجع حالة محدثة |
| الحافة (Edge) | الاتصال بين العقد — يمكن أن يكون ثابتاً أو شرطياً |
| الرسم البياني (Graph) | سير العمل الكامل: عقد + حواف + مخطط الحالة |
لماذا لا نربط الدوال ببساطة؟ لأن الوكلاء الحقيقيين يحتاجون منطق تفرع. الوكيل قد يحتاج لاستدعاء أداة، فحص النتيجة، استدعاء أداة أخرى، ثم صياغة الرد. LangGraph يجعل هذا واضحاً وقابلاً للتتبع.
الخطوة 1: إعداد المشروع
أنشئ مشروعاً جديداً وثبّت المكتبات:
mkdir ai-agent-langgraph && cd ai-agent-langgraph
npm init -y
npm install @langchain/langgraph @langchain/openai @langchain/core zod
npm install -D typescript tsx @types/nodeهيّئ TypeScript:
npx tsc --initحدّث ملف tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true
},
"include": ["src/**/*"]
}أنشئ ملف .env لمفتاح الـ API:
OPENAI_API_KEY=sk-your-key-hereهيكل المشروع:
ai-agent-langgraph/
├── src/
│ ├── agent.ts # الرسم البياني الرئيسي للوكيل
│ ├── tools.ts # تعريف الأدوات
│ ├── state.ts # مخطط الحالة
│ └── index.ts # نقطة الدخول
├── .env
├── tsconfig.json
└── package.json
الخطوة 2: تعريف حالة الوكيل
الحالة هي العمود الفقري للوكيل. كل عقدة تقرأ منها وتكتب إليها.
أنشئ ملف src/state.ts:
import { Annotation, MessagesAnnotation } from "@langchain/langgraph";
// تعريف مخطط الحالة للوكيل
export const AgentState = Annotation.Root({
// الرسائل تتراكم خلال المحادثة
...MessagesAnnotation.spec,
// تتبع عدد استدعاءات الأدوات (للتصحيح)
toolCallCount: Annotation<number>({
reducer: (current, update) => (update ?? current ?? 0),
default: () => 0,
}),
// الإجابة النهائية من الوكيل
finalAnswer: Annotation<string>({
reducer: (current, update) => update ?? current ?? "",
default: () => "",
}),
});
export type AgentStateType = typeof AgentState.State;المفاهيم الأساسية:
MessagesAnnotation— توصيف مدمج يتعامل مع تراكم الرسائل. الرسائل الجديدة تُضاف تلقائياً للقائمة.Annotation— يعرّف حقل حالة مع نوع محدد وreducer(طريقة دمج التحديثات) وقيمة افتراضية.- المُخفِّضات (Reducers) — دوال تحدد كيفية دمج القيم الجديدة مع الحالة الحالية.
💡 نمط المُخفِّض هو ما يجعل LangGraph قوياً. كل عقدة تُرجع تحديثاً جزئياً، والإطار يعرف كيف يدمجه بشكل صحيح.
الخطوة 3: إنشاء الأدوات
الأدوات هي الدوال التي يستطيع الذكاء الاصطناعي استدعاءها. LangGraph يستخدم تنسيق أدوات LangChain — تعرّف الاسم والوصف ومخطط المدخلات والتنفيذ.
أنشئ ملف src/tools.ts:
import { tool } from "@langchain/core/tools";
import { z } from "zod";
// الأداة 1: آلة حاسبة
export const calculatorTool = tool(
async ({ expression }) => {
try {
const sanitized = expression.replace(/[^0-9+\-*/().%\s]/g, "");
if (!sanitized || sanitized !== expression.trim()) {
return "خطأ: تعبير غير صالح. يُسمح فقط بالأرقام والعمليات الأساسية (+, -, *, /, %).";
}
const result = new Function(`return (${sanitized})`)();
return `النتيجة: ${result}`;
} catch (error) {
return `خطأ في الحساب: ${(error as Error).message}`;
}
},
{
name: "calculator",
description:
"ينفذ عمليات حسابية. المدخل يجب أن يكون تعبيراً رياضياً مثل '2 + 2' أو '(10 * 5) / 3'.",
schema: z.object({
expression: z
.string()
.describe("التعبير الرياضي المراد حسابه"),
}),
}
);
// الأداة 2: بحث الويب (محاكاة لأغراض الدرس)
export const webSearchTool = tool(
async ({ query }) => {
console.log(`[أداة] البحث في الويب عن: "${query}"`);
const results = [
{
title: `أفضل نتيجة لـ: ${query}`,
snippet: `معلومات شاملة حول ${query}. يغطي أحدث التطورات والحقائق الرئيسية حتى 2026.`,
url: `https://example.com/search?q=${encodeURIComponent(query)}`,
},
];
return JSON.stringify(results, null, 2);
},
{
name: "web_search",
description:
"يبحث في الويب عن معلومات حديثة. استخدمه عندما تحتاج حقائق أو أخبار أو بيانات محدثة.",
schema: z.object({
query: z.string().describe("استعلام البحث"),
}),
}
);
// الأداة 3: التاريخ والوقت
export const dateTimeTool = tool(
async ({ timezone }) => {
const now = new Date();
const formatter = new Intl.DateTimeFormat("ar-SA", {
timeZone: timezone || "UTC",
dateStyle: "full",
timeStyle: "long",
});
return formatter.format(now);
},
{
name: "get_current_datetime",
description:
"يحصل على التاريخ والوقت الحالي. يمكن تحديد المنطقة الزمنية مثل 'Asia/Riyadh' أو 'Africa/Tunis'.",
schema: z.object({
timezone: z
.string()
.optional()
.describe("اسم المنطقة الزمنية IANA (الافتراضي: UTC)"),
}),
}
);
export const allTools = [calculatorTool, webSearchTool, dateTimeTool];⚠️ ملاحظة أمنية: أداة الآلة الحاسبة تستخدم تنقية بسيطة. في الإنتاج، استخدم محلل رياضي آمن مثل
mathjsبدلاً منnew Function().
الخطوة 4: بناء الرسم البياني للوكيل
هذا هو جوهر الدرس. سننشئ رسماً بيانياً حيث:
- عقدة النموذج اللغوي تستقبل الرسائل وتقرر ما يجب فعله
- إذا أرادت استخدام أدوات ← التوجيه إلى عقدة الأدوات
- عقدة الأدوات تنفذ الأدوات وتعيد النتائج
- العودة إلى عقدة النموذج لمعالجة النتائج
- عندما يملك النموذج إجابة نهائية ← الانتهاء
أنشئ ملف src/agent.ts:
import { StateGraph, END, START } from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";
import { ToolNode } from "@langchain/langgraph/prebuilt";
import {
AIMessage,
HumanMessage,
SystemMessage,
} from "@langchain/core/messages";
import { AgentState } from "./state.js";
import { allTools } from "./tools.js";
// تهيئة النموذج اللغوي مع ربط الأدوات
const llm = new ChatOpenAI({
model: "gpt-4o",
temperature: 0,
}).bindTools(allTools);
// التوجيه النظامي الذي يحدد سلوك الوكيل
const SYSTEM_PROMPT = `أنت مساعد ذكي لديك وصول لأدوات.
قدراتك:
- calculator: لأي عمليات حسابية
- web_search: للبحث عن معلومات حديثة
- get_current_datetime: للحصول على التاريخ والوقت
إرشادات:
- استخدم الأدوات عندما تحتاج بيانات واقعية أو حسابات
- فكّر خطوة بخطوة للأسئلة المعقدة
- إذا أرجعت أداة خطأ، اشرحه للمستخدم
- كن موجزاً لكن شاملاً في إجاباتك النهائية`;
// العقدة 1: استدعاء النموذج اللغوي
async function callModel(
state: typeof AgentState.State
): Promise<Partial<typeof AgentState.State>> {
const messages = [new SystemMessage(SYSTEM_PROMPT), ...state.messages];
const response = await llm.invoke(messages);
return { messages: [response] };
}
// العقدة 2: تنفيذ الأدوات
const toolNode = new ToolNode(allTools);
// حافة شرطية: هل نواصل للأدوات أم ننتهي؟
function shouldContinue(
state: typeof AgentState.State
): "tools" | typeof END {
const lastMessage = state.messages[state.messages.length - 1];
if (
lastMessage instanceof AIMessage &&
lastMessage.tool_calls &&
lastMessage.tool_calls.length > 0
) {
return "tools";
}
return END;
}
// بناء الرسم البياني
export function createAgentGraph() {
const graph = new StateGraph(AgentState)
.addNode("agent", callModel)
.addNode("tools", toolNode)
.addEdge(START, "agent")
.addConditionalEdges("agent", shouldContinue, {
tools: "tools",
[END]: END,
})
.addEdge("tools", "agent");
return graph.compile();
}مخطط بصري للرسم البياني:
┌─────────┐
│ بداية │
└────┬─────┘
│
▼
┌─────────┐ يوجد استدعاء أدوات ┌─────────┐
│ الوكيل │ ────────────────────► │ الأدوات │
│ (LLM) │ ◄──────────────────── │ (تنفيذ) │
└────┬─────┘ إرجاع النتائج └──────────┘
│
│ لا يوجد استدعاء أدوات
▼
┌─────────┐
│ نهاية │
└──────────┘
🚀 تحتاج مساعدة في تنفيذ وكلاء الذكاء الاصطناعي في منتجك؟ نقطة تبني حلول ذكاء اصطناعي للفرق التي تريد نتائج جاهزة للإنتاج، لا نماذج أولية.
الخطوة 5: تشغيل الوكيل
أنشئ ملف src/index.ts:
import "dotenv/config";
import { HumanMessage } from "@langchain/core/messages";
import { createAgentGraph } from "./agent.js";
async function main() {
const agent = createAgentGraph();
console.log("🤖 الوكيل جاهز. لنختبر بعض الاستعلامات.\n");
// اختبار 1: عملية حسابية
console.log("--- اختبار 1: رياضيات ---");
const result1 = await agent.invoke({
messages: [
new HumanMessage(
"ما هو 15% من 2,340؟ وأضف 99 للنتيجة."
),
],
});
const lastMsg1 = result1.messages[result1.messages.length - 1];
console.log("الإجابة:", lastMsg1.content, "\n");
// اختبار 2: بحث في الويب
console.log("--- اختبار 2: بحث ---");
const result2 = await agent.invoke({
messages: [
new HumanMessage(
"ابحث عن أحدث اتجاهات تطوير TypeScript في 2026"
),
],
});
const lastMsg2 = result2.messages[result2.messages.length - 1];
console.log("الإجابة:", lastMsg2.content, "\n");
// اختبار 3: استخدام أدوات متعددة
console.log("--- اختبار 3: أدوات متعددة ---");
const result3 = await agent.invoke({
messages: [
new HumanMessage(
"كم الساعة الآن في طوكيو؟ واحسب كم ساعة متبقية حتى منتصف الليل هناك."
),
],
});
const lastMsg3 = result3.messages[result3.messages.length - 1];
console.log("الإجابة:", lastMsg3.content, "\n");
}
main().catch(console.error);شغّل الوكيل:
npx tsx src/index.tsسترى الوكيل يفكر في كل سؤال، يستدعي الأدوات حسب الحاجة، ويعيد إجابات متماسكة.
الخطوة 6: إضافة ذاكرة المحادثة
الوكيل عديم الحالة ينسى كل شيء بعد كل استدعاء. لنضف ذاكرة مستمرة حتى يتذكر الوكيل الجولات السابقة.
أنشئ ملف src/memory-agent.ts:
import "dotenv/config";
import { StateGraph, END, START, MemorySaver } from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";
import { ToolNode } from "@langchain/langgraph/prebuilt";
import {
AIMessage,
HumanMessage,
SystemMessage,
} from "@langchain/core/messages";
import { AgentState } from "./state.js";
import { allTools } from "./tools.js";
const memory = new MemorySaver();
const llm = new ChatOpenAI({ model: "gpt-4o", temperature: 0 }).bindTools(
allTools
);
const SYSTEM_PROMPT = `أنت مساعد ذكي مع ذاكرة.
تتذكر الرسائل السابقة في المحادثة.
استخدم الأدوات عند الحاجة: calculator, web_search, get_current_datetime.`;
async function callModel(state: typeof AgentState.State) {
const messages = [new SystemMessage(SYSTEM_PROMPT), ...state.messages];
const response = await llm.invoke(messages);
return { messages: [response] };
}
function shouldContinue(state: typeof AgentState.State) {
const last = state.messages[state.messages.length - 1];
if (
last instanceof AIMessage &&
last.tool_calls &&
last.tool_calls.length > 0
) {
return "tools";
}
return END;
}
const agentWithMemory = new StateGraph(AgentState)
.addNode("agent", callModel)
.addNode("tools", new ToolNode(allTools))
.addEdge(START, "agent")
.addConditionalEdges("agent", shouldContinue, {
tools: "tools",
[END]: END,
})
.addEdge("tools", "agent")
.compile({ checkpointer: memory }); // ← الذاكرة مفعّلة!
async function main() {
// إعدادات مع معرّف المحادثة
const config = { configurable: { thread_id: "user-123" } };
// الجولة 1
console.log("👤 المستخدم: اسمي سارة وأعمل في شركة ناشئة.");
const res1 = await agentWithMemory.invoke(
{
messages: [
new HumanMessage("اسمي سارة وأعمل في شركة ناشئة."),
],
},
config
);
console.log(
"🤖 الوكيل:",
res1.messages[res1.messages.length - 1].content
);
console.log();
// الجولة 2 — الوكيل يجب أن يتذكر الاسم
console.log("👤 المستخدم: ما اسمي؟");
const res2 = await agentWithMemory.invoke(
{ messages: [new HumanMessage("ما اسمي؟")] },
config
);
console.log(
"🤖 الوكيل:",
res2.messages[res2.messages.length - 1].content
);
console.log();
// الجولة 3 — خطوات متعددة مع سياق الذاكرة
console.log("👤 المستخدم: احسب عدد حروف اسمي مضروباً في 100.");
const res3 = await agentWithMemory.invoke(
{
messages: [
new HumanMessage("احسب عدد حروف اسمي مضروباً في 100."),
],
},
config
);
console.log(
"🤖 الوكيل:",
res3.messages[res3.messages.length - 1].content
);
}
main().catch(console.error);شغّله:
npx tsx src/memory-agent.tsالوكيل يتذكر الآن أن اسم المستخدم سارة عبر الجولات. thread_id يعمل كمعرّف للجلسة — معرّفات مختلفة تعطيك محادثات معزولة.
نصيحة:
MemorySaverيحفظ الحالة في الذاكرة (تُفقد عند إعادة التشغيل). للإنتاج، استخدمPostgresSaverأوSqliteSaverمن حزم@langchain/langgraph-checkpoint-*.
الخطوة 7: معالجة الأخطاء وإعادة المحاولة
الوكلاء في بيئة الإنتاج يحتاجون معالجة أخطاء قوية. لنضف غلاف إعادة محاولة وحدود أمان.
أنشئ ملف src/utils.ts:
import { AIMessage } from "@langchain/core/messages";
// غلاف إعادة المحاولة مع تراجع أسي
export function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3
): Promise<T> {
return new Promise(async (resolve, reject) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const result = await fn();
return resolve(result);
} catch (error) {
console.warn(
`المحاولة ${attempt}/${maxRetries} فشلت:`,
(error as Error).message
);
if (attempt === maxRetries) {
return reject(error);
}
await new Promise((r) =>
setTimeout(r, Math.pow(2, attempt) * 1000)
);
}
}
});
}
// غلاف المهلة الزمنية
export async function invokeWithTimeout(
agent: any,
input: any,
config: any,
timeoutMs = 30000
) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
try {
const result = await agent.invoke(input, {
...config,
signal: controller.signal,
});
return result;
} catch (error) {
if ((error as Error).name === "AbortError") {
throw new Error(
`انتهت المهلة الزمنية للوكيل بعد ${timeoutMs}ms. الاستعلام قد يكون معقداً جداً.`
);
}
throw error;
} finally {
clearTimeout(timeout);
}
}
// تتبع استهلاك التوكنات
export function extractTokenUsage(result: any) {
const messages = result.messages || [];
let totalTokens = 0;
for (const msg of messages) {
if (msg instanceof AIMessage && msg.usage_metadata) {
totalTokens +=
(msg.usage_metadata.input_tokens || 0) +
(msg.usage_metadata.output_tokens || 0);
}
}
return totalTokens;
}هذه الأدوات توفر لك:
- إعادة المحاولة مع تراجع أسي — يعالج أعطال API المؤقتة
- حماية المهلة الزمنية — يمنع الحلقات اللانهائية
- تتبع التوكنات — يراقب التكاليف لكل استدعاء
الخطوة 8: بث الاستجابات
لتجربة مستخدم أفضل، ابث مخرجات الوكيل كلمة بكلمة بدلاً من الانتظار للاستجابة الكاملة.
أنشئ ملف src/stream.ts:
import "dotenv/config";
import { HumanMessage } from "@langchain/core/messages";
import { createAgentGraph } from "./agent.js";
async function streamAgent() {
const agent = createAgentGraph();
const input = {
messages: [
new HumanMessage(
"اشرح الحوسبة الكمية بشكل مبسط، ثم احسب 2^64."
),
],
};
console.log("🤖 بث الاستجابة:\n");
for await (const event of await agent.streamEvents(input, {
version: "v2",
})) {
if (event.event === "on_chat_model_stream") {
const chunk = event.data.chunk;
if (chunk.content) {
process.stdout.write(chunk.content);
}
}
if (event.event === "on_tool_start") {
console.log(`\n\n🔧 استدعاء أداة: ${event.name}`);
console.log(` المدخل: ${JSON.stringify(event.data.input)}`);
}
if (event.event === "on_tool_end") {
console.log(` النتيجة: ${event.data.output.content}\n`);
}
}
console.log("\n\n✅ اكتمل البث.");
}
streamAgent().catch(console.error);شغّله:
npx tsx src/stream.tsالخطوة 9: استخدام مزودي LLM بديلين
لست مقيداً بـ OpenAI. LangGraph.js يعمل مع أي نموذج متوافق مع LangChain:
Anthropic (Claude)
npm install @langchain/anthropicimport { ChatAnthropic } from "@langchain/anthropic";
const llm = new ChatAnthropic({
model: "claude-sonnet-4-20250514",
temperature: 0,
}).bindTools(allTools);Google Gemini
npm install @langchain/google-genaiimport { ChatGoogleGenerativeAI } from "@langchain/google-genai";
const llm = new ChatGoogleGenerativeAI({
model: "gemini-2.0-flash",
temperature: 0,
}).bindTools(allTools);نماذج محلية عبر Ollama
npm install @langchain/ollamaimport { ChatOllama } from "@langchain/ollama";
const llm = new ChatOllama({
model: "llama3.3",
temperature: 0,
}).bindTools(allTools);نصيحة: للإنتاج، فكّر في تشغيل عدة مزودين مع سلسلة احتياطية. إذا تعطل OpenAI، انتقل تلقائياً إلى Anthropic.
الخطوة 10: اعتبارات الإنتاج
قبل نشر الوكيل، عالج هذه النقاط:
1. تحديد المعدل
import { RateLimiter } from "limiter";
const limiter = new RateLimiter({
tokensPerInterval: 10,
interval: "minute",
});
async function rateLimitedInvoke(agent: any, input: any) {
await limiter.removeTokens(1);
return agent.invoke(input);
}2. المراقبة مع LangSmith
npm install langsmithLANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=your-langsmith-key
LANGCHAIN_PROJECT=my-ai-agent3. الإنسان في الحلقة
للإجراءات الحساسة (إرسال بريد، عمليات شراء)، أضف خطوة موافقة:
import { interrupt } from "@langchain/langgraph";
async function sensitiveToolNode(state: typeof AgentState.State) {
const lastMessage = state.messages[state.messages.length - 1];
const approval = interrupt({
action: "tool_call",
description: "الوكيل يريد تنفيذ إجراء حساس",
toolCalls: (lastMessage as any).tool_calls,
});
if (!approval.approved) {
return {
messages: [new HumanMessage("تم رفض الإجراء من المستخدم.")],
};
}
const toolNode = new ToolNode(allTools);
return toolNode.invoke(state);
}4. التحكم في التكاليف
حدد الحد الأقصى لاستدعاءات LLM لكل تنفيذ:
const MAX_ITERATIONS = 10;
function shouldContinue(state: typeof AgentState.State) {
const aiMessages = state.messages.filter(
(m) => m instanceof AIMessage
);
if (aiMessages.length >= MAX_ITERATIONS) {
console.warn("تم الوصول للحد الأقصى من التكرارات");
return END;
}
const last = state.messages[state.messages.length - 1];
if (last instanceof AIMessage && last.tool_calls?.length > 0) {
return "tools";
}
return END;
}الخلاصة
بنيت نظام وكيل ذكاء اصطناعي متكامل مع LangGraph.js:
| ما بنيته | لماذا مهم |
|---|---|
| مخطط الحالة مع التوصيفات | تدفق بيانات آمن النوع عبر الوكيل |
| تعريفات أدوات مع مخططات Zod | الذكاء الاصطناعي يستدعي دوال خارجية بأمان |
| سير عمل قائم على الرسم البياني | منطق وكيل واضح وقابل للتصحيح |
| توجيه شرطي | الوكيل يقرر مساره بنفسه |
| ذاكرة المحادثة | تفاعلات متعددة الجولات |
| معالجة أخطاء وإعادة محاولة | مرونة في الإنتاج |
| بث الاستجابات | تجربة مستخدم أفضل |
| دعم متعدد المزودين | لا ارتباط بمزود واحد |
النقاط الرئيسية:
- الرسوم البيانية أفضل من السلاسل — عندما يحتاج الوكيل منطق تفرع، LangGraph يجعله واضحاً
- الحالة هي الملك — صمم مخطط الحالة بعناية؛ كل شيء يمر عبره
- الأدوات تحتاج مخططات — أدوات موصوفة جيداً مع Zod تساعد LLM على اتخاذ قرارات أفضل
- الذاكرة تحتاج استمرارية — استخدم
PostgresSaverأوSqliteSaverفي الإنتاج - أضف دائماً حدود أمان — حد أقصى للتكرارات، مهلات زمنية، وتحديد معدل
الخطوات التالية
- أضف المزيد من الأدوات (استعلامات قواعد بيانات، إرسال بريد، عمليات ملفات)
- نفّذ رسوم بيانية فرعية لتنسيق وكلاء متعددين
- انشر كـ API مع Express أو Hono
- أضف تتبع LangSmith لمراقبة الإنتاج
- استكشف LangGraph Studio للتصحيح البصري
💡 جاهز للانتقال من القراءة للتطبيق؟ تحدث مع فريقنا حول تصميم ونشر أنظمة وكلاء ذكاء اصطناعي تتكامل مع بنيتك التقنية الحالية.
ناقش مشروعك معنا
نحن هنا للمساعدة في احتياجات تطوير الويب الخاصة بك. حدد موعدًا لمناقشة مشروعك وكيف يمكننا مساعدتك.
دعنا نجد أفضل الحلول لاحتياجاتك.
مقالات ذات صلة

مقدمة في بروتوكول سياق النموذج (MCP)
تعلم عن بروتوكول سياق النموذج (MCP)، وحالات استخدامه، ومزاياه، وكيفية بناء واستخدام خادم MCP مع TypeScript.

بناء أداة استخراج بيانات ذكية من الويب باستخدام Playwright و Claude API في TypeScript
تعلّم كيف تبني أداة استخراج بيانات ذكية تستخدم Playwright للتحكم بالمتصفح وClaude AI لفهم صفحات الويب واستخراج بيانات منظّمة — بدون محددات CSS هشّة.

بناء مفسر أكواد مخصص لوكلاء نماذج اللغة الكبيرة
تعلم كيفية إنشاء مفسر أكواد مخصص لوكلاء نماذج اللغة الكبيرة (LLM)، مما يتيح استدعاء الأدوات الديناميكي وتنفيذ الأكواد المعزول لتعزيز المرونة والأمان.