واجهة Mistral AI مع TypeScript: بناء تطبيقات ذكية

Mistral AI، الشركة الفرنسية الناشئة التي أصبحت من أبرز الرواد العالميين في مجال الذكاء الاصطناعي التوليدي، تقدّم نماذج لغوية عالية الأداء يمكن الوصول إليها عبر واجهة برمجية بسيطة. في هذا الدرس، سنستكشف كيفية دمج واجهة Mistral AI في تطبيق TypeScript، مع تغطية المحادثة، التوليد المنظّم، استدعاء الدوال (Function Calling)، والتوليد المعزّز بالاسترجاع (RAG).
لماذا Mistral AI؟ نماذج Mistral تقدّم نسبة جودة/سعر ممتازة، وزمن استجابة منخفض، وهي متاحة كنماذج مفتوحة الأوزان. Mistral Large ينافس GPT-4 وClaude في العديد من المعايير، بينما Mistral Small مثالي للمهام السريعة بتكلفة منخفضة.
ما ستتعلّمه
- إعداد SDK الخاص بـ Mistral AI مع TypeScript
- بناء روبوت محادثة مع سجل المحادثات
- استخدام التوليد المنظّم (وضع JSON)
- تنفيذ استدعاء الدوال لربط الذكاء الاصطناعي بالعالم الحقيقي
- بناء نظام RAG بسيط مع تضمينات Mistral
- التعامل مع البث المباشر للردود لتجربة مستخدم سلسة
- أفضل الممارسات للإنتاج (تحديد المعدل، معالجة الأخطاء، التكاليف)
المتطلبات الأساسية
قبل البدء، تأكد من توفر:
- Node.js 20+ مثبّت
- TypeScript 5+ مهيّأ
- حساب Mistral AI مع مفتاح API (أنشئ حسابًا على console.mistral.ai)
- معرفة أساسية بـ TypeScript و async/await
- محرر أكواد (VS Code يُنصح به)
نماذج Mistral في 2026
تقدّم Mistral عدة نماذج مناسبة لحالات استخدام مختلفة:
| النموذج | حالة الاستخدام | السياق | نقاط القوة |
|---|---|---|---|
| Mistral Large | التفكير المعقّد، البرمجة | 128 ألف رمز | أداء قريب من GPT-4o |
| Mistral Medium | الاستخدام العام | 32 ألف رمز | توازن جيد بين التكلفة والأداء |
| Mistral Small | المهام البسيطة، التصنيف | 32 ألف رمز | سريع جدًا، اقتصادي |
| Codestral | توليد الأكواد | 32 ألف رمز | متخصص في البرمجة |
| Mistral Embed | التضمينات | 8 آلاف رمز | البحث الدلالي |
الخطوة 1: تهيئة المشروع
لنُنشئ مشروع TypeScript نظيف مع جميع المتطلبات:
mkdir mistral-ts-app && cd mistral-ts-app
npm init -y
npm install @mistralai/mistralai zod dotenv
npm install -D typescript tsx @types/nodeهيّئ إعدادات TypeScript:
npx tsc --initعدّل tsconfig.json لإعداد حديث:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": "./src",
"resolveJsonModule": true,
"declaration": true
},
"include": ["src/**/*"]
}أنشئ هيكل المشروع:
mkdir -p src/{chat,structured,functions,rag,utils}الخطوة 2: إعداد عميل Mistral
أنشئ ملف .env في جذر المشروع:
MISTRAL_API_KEY=مفتاح_الـAPI_الخاص_بكثم أنشئ عميل Mistral في src/utils/client.ts:
// src/utils/client.ts
import { Mistral } from "@mistralai/mistralai";
import dotenv from "dotenv";
dotenv.config();
const apiKey = process.env.MISTRAL_API_KEY;
if (!apiKey) {
throw new Error(
"MISTRAL_API_KEY مفقود. أضفه إلى ملف .env"
);
}
export const mistral = new Mistral({ apiKey });
// النماذج المتاحة
export const MODELS = {
LARGE: "mistral-large-latest",
MEDIUM: "mistral-medium-latest",
SMALL: "mistral-small-latest",
CODESTRAL: "codestral-latest",
EMBED: "mistral-embed",
} as const;لنختبر الاتصال بسرعة:
// src/test-connection.ts
import { mistral, MODELS } from "./utils/client";
async function testConnection() {
const response = await mistral.chat.complete({
model: MODELS.SMALL,
messages: [
{ role: "user", content: "أجب بكلمة واحدة: هل يعمل هذا؟" },
],
});
console.log("الرد:", response.choices?.[0]?.message?.content);
}
testConnection();شغّله باستخدام:
npx tsx src/test-connection.tsالخطوة 3: روبوت محادثة مع سجل المحادثات
لنبنِ روبوت محادثة يحافظ على سياق المحادثة:
// src/chat/chatbot.ts
import { mistral, MODELS } from "../utils/client";
import readline from "readline";
interface Message {
role: "system" | "user" | "assistant";
content: string;
}
class MistralChatbot {
private history: Message[] = [];
private model: string;
constructor(systemPrompt: string, model = MODELS.LARGE) {
this.model = model;
this.history.push({
role: "system",
content: systemPrompt,
});
}
async chat(userMessage: string): Promise<string> {
this.history.push({ role: "user", content: userMessage });
const response = await mistral.chat.complete({
model: this.model,
messages: this.history,
temperature: 0.7,
maxTokens: 1024,
});
const assistantMessage =
response.choices?.[0]?.message?.content ?? "";
this.history.push({
role: "assistant",
content: assistantMessage,
});
return assistantMessage;
}
// تقليم السجل لتجنب تجاوز حدود السياق
trimHistory(maxMessages: number = 20) {
if (this.history.length > maxMessages + 1) {
const systemMessage = this.history[0];
this.history = [
systemMessage,
...this.history.slice(-(maxMessages)),
];
}
}
}
async function main() {
const bot = new MistralChatbot(
"أنت مساعد تقني خبير في تطوير الويب. " +
"تجيب بإيجاز ودقة باللغة العربية."
);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log("روبوت Mistral جاهز! اكتب 'quit' للخروج.\n");
const askQuestion = () => {
rl.question("أنت: ", async (input) => {
if (input.toLowerCase() === "quit") {
rl.close();
return;
}
const response = await bot.chat(input);
console.log(`\nالمساعد: ${response}\n`);
bot.trimHistory();
askQuestion();
});
};
askQuestion();
}
main();شغّل الروبوت:
npx tsx src/chat/chatbot.tsالخطوة 4: بث الردود مباشرة
لتجربة مستخدم سلسة، يمكن بث الردود رمزًا برمز:
// src/chat/streaming.ts
import { mistral, MODELS } from "../utils/client";
async function streamChat(prompt: string) {
const stream = await mistral.chat.stream({
model: MODELS.LARGE,
messages: [
{
role: "system",
content: "أنت مساعد إبداعي يكتب قصصًا قصيرة.",
},
{ role: "user", content: prompt },
],
});
process.stdout.write("المساعد: ");
for await (const event of stream) {
const content = event.data?.choices?.[0]?.delta?.content;
if (content) {
process.stdout.write(content);
}
}
console.log("\n");
}
streamChat(
"اروِ قصة من 3 جمل عن مطوّر يكتشف الذكاء الاصطناعي."
);الأداء: البث يقلّل وقت الاستجابة المُدرَك لأن المستخدم يرى أول الرموز فورًا، بدلاً من انتظار التوليد الكامل.
الخطوة 5: التوليد المنظّم (وضع JSON)
من أبرز مزايا Mistral القدرة على توليد ردود JSON منظّمة، مثالية للواجهات البرمجية:
// src/structured/json-generation.ts
import { mistral, MODELS } from "../utils/client";
import { z } from "zod";
const ProductReviewSchema = z.object({
sentiment: z.enum(["إيجابي", "سلبي", "محايد"]),
score: z.number().min(0).max(10),
strengths: z.array(z.string()),
weaknesses: z.array(z.string()),
summary: z.string(),
});
type ProductReview = z.infer<typeof ProductReviewSchema>;
async function analyzeReview(reviewText: string): Promise<ProductReview> {
const response = await mistral.chat.complete({
model: MODELS.LARGE,
messages: [
{
role: "system",
content: `أنت محلّل مراجعات المنتجات.
أجب فقط بـ JSON صالح بهذا التنسيق بالضبط:
{
"sentiment": "إيجابي" | "سلبي" | "محايد",
"score": number (0-10),
"strengths": string[],
"weaknesses": string[],
"summary": string
}`,
},
{
role: "user",
content: `حلّل هذه المراجعة: "${reviewText}"`,
},
],
responseFormat: { type: "json_object" },
temperature: 0.1,
});
const content = response.choices?.[0]?.message?.content ?? "{}";
const parsed = JSON.parse(content);
return ProductReviewSchema.parse(parsed);
}
async function main() {
const reviews = [
"منتج ممتاز! الجودة عالية والتوصيل سريع. العيب الوحيد هو السعر المرتفع قليلاً.",
"مخيّب جدًا للآمال. المنتج لا يطابق الوصف وخدمة العملاء غير موجودة.",
"مقبول مقابل السعر. لا شيء استثنائي لكنه يؤدي الغرض.",
];
for (const review of reviews) {
console.log(`\nالمراجعة: "${review.substring(0, 50)}..."`);
const analysis = await analyzeReview(review);
console.log("التحليل:", JSON.stringify(analysis, null, 2));
}
}
main();الخطوة 6: استدعاء الدوال (Function Calling)
يسمح استدعاء الدوال لـ Mistral بتنفيذ دوال في شفرتك للتفاعل مع العالم الخارجي. هذه هي الميزة الرئيسية لبناء وكلاء الذكاء الاصطناعي:
// src/functions/weather-agent.ts
import { mistral, MODELS } from "../utils/client";
const tools = [
{
type: "function" as const,
function: {
name: "get_weather",
description: "الحصول على الطقس الحالي لمدينة معينة",
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "اسم المدينة (مثل: تونس، باريس)",
},
unit: {
type: "string",
enum: ["celsius", "fahrenheit"],
description: "وحدة الحرارة",
},
},
required: ["city"],
},
},
},
{
type: "function" as const,
function: {
name: "get_exchange_rate",
description: "الحصول على سعر الصرف بين عملتين",
parameters: {
type: "object",
properties: {
from: { type: "string", description: "العملة المصدر (مثل: EUR)" },
to: { type: "string", description: "العملة الهدف (مثل: TND)" },
},
required: ["from", "to"],
},
},
},
];
function getWeather(city: string, unit = "celsius") {
const mockData: Record<string, { temp: number; condition: string }> = {
tunis: { temp: 24, condition: "مشمس" },
paris: { temp: 15, condition: "غائم" },
london: { temp: 12, condition: "ممطر" },
};
const data = mockData[city.toLowerCase()] ?? {
temp: 20,
condition: "غير معروف",
};
return JSON.stringify({
city,
temperature: data.temp,
unit,
condition: data.condition,
});
}
function getExchangeRate(from: string, to: string) {
const rates: Record<string, number> = {
"EUR-TND": 3.35,
"USD-TND": 3.10,
"EUR-USD": 1.08,
};
const key = `${from.toUpperCase()}-${to.toUpperCase()}`;
const rate = rates[key] ?? 1.0;
return JSON.stringify({ from, to, rate, timestamp: new Date().toISOString() });
}
function executeFunction(name: string, args: string): string {
const parsedArgs = JSON.parse(args);
switch (name) {
case "get_weather":
return getWeather(parsedArgs.city, parsedArgs.unit);
case "get_exchange_rate":
return getExchangeRate(parsedArgs.from, parsedArgs.to);
default:
return JSON.stringify({ error: `دالة غير معروفة: ${name}` });
}
}
async function agentChat(userMessage: string) {
console.log(`\nالمستخدم: ${userMessage}`);
const messages: any[] = [
{
role: "system",
content:
"أنت مساعد يمكنه التحقق من الطقس وأسعار الصرف. " +
"استخدم الأدوات المتاحة للإجابة ببيانات دقيقة.",
},
{ role: "user", content: userMessage },
];
let response = await mistral.chat.complete({
model: MODELS.LARGE,
messages,
tools,
});
let choice = response.choices?.[0];
while (choice?.finishReason === "tool_calls" && choice.message?.toolCalls) {
const toolCalls = choice.message.toolCalls;
messages.push(choice.message);
for (const toolCall of toolCalls) {
const functionName = toolCall.function.name;
const functionArgs = toolCall.function.arguments;
console.log(` [استدعاء] ${functionName}(${functionArgs})`);
const result = executeFunction(functionName, functionArgs);
messages.push({
role: "tool",
toolCallId: toolCall.id,
content: result,
});
}
response = await mistral.chat.complete({
model: MODELS.LARGE,
messages,
tools,
});
choice = response.choices?.[0];
}
console.log(`المساعد: ${choice?.message?.content}\n`);
}
async function main() {
await agentChat("ما الطقس في تونس وما سعر صرف EUR/TND؟");
await agentChat("قارن الطقس بين باريس وتونس.");
}
main();الأمان: في بيئة الإنتاج، تحقّق دائمًا من معاملات الدوال قبل تنفيذها. لا تثق أبدًا بمدخلات النموذج دون تحقّق — استخدم Zod أو أي أداة تحقّق مخطط أخرى.
الخطوة 7: RAG مع تضمينات Mistral
التوليد المعزّز بالاسترجاع (RAG) يتيح لك الإجابة على الأسئلة بالاعتماد على مستنداتك الخاصة. إليك التنفيذ الكامل:
// src/rag/vector-store.ts
interface Document {
id: string;
content: string;
metadata: Record<string, string>;
embedding?: number[];
}
function cosineSimilarity(a: number[], b: number[]): number {
let dotProduct = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
export class SimpleVectorStore {
private documents: Document[] = [];
add(doc: Document) {
this.documents.push(doc);
}
search(queryEmbedding: number[], topK = 3): Document[] {
const scored = this.documents
.filter((doc) => doc.embedding)
.map((doc) => ({
doc,
score: cosineSimilarity(queryEmbedding, doc.embedding!),
}))
.sort((a, b) => b.score - a.score);
return scored.slice(0, topK).map((s) => s.doc);
}
}الآن نظام RAG الكامل:
// src/rag/rag-system.ts
import { mistral, MODELS } from "../utils/client";
import { SimpleVectorStore } from "./vector-store";
class MistralRAG {
private store = new SimpleVectorStore();
async embed(texts: string[]): Promise<number[][]> {
const response = await mistral.embeddings.create({
model: MODELS.EMBED,
inputs: texts,
});
return response.data.map((d) => d.embedding);
}
async indexDocuments(
documents: { id: string; content: string; metadata: Record<string, string> }[]
) {
const contents = documents.map((d) => d.content);
const embeddings = await this.embed(contents);
documents.forEach((doc, i) => {
this.store.add({
...doc,
embedding: embeddings[i],
});
});
console.log(`تم فهرسة ${documents.length} مستند.`);
}
async query(question: string): Promise<string> {
const [queryEmbedding] = await this.embed([question]);
const relevantDocs = this.store.search(queryEmbedding, 3);
const context = relevantDocs
.map((doc) => `[${doc.metadata.source}]\n${doc.content}`)
.join("\n\n---\n\n");
const response = await mistral.chat.complete({
model: MODELS.LARGE,
messages: [
{
role: "system",
content: `أنت مساعد يجيب على الأسئلة بناءً فقط على السياق المقدم. إذا لم يحتوِ السياق على الإجابة، قل ذلك بوضوح.
السياق:
${context}`,
},
{ role: "user", content: question },
],
temperature: 0.2,
});
return response.choices?.[0]?.message?.content ?? "لا توجد إجابة";
}
}
async function main() {
const rag = new MistralRAG();
await rag.indexDocuments([
{
id: "1",
content:
"Next.js 15 يقدم Partial Prerendering (PPR)، الذي يجمع بين " +
"العرض الثابت والديناميكي في صفحة واحدة. المكونات الثابتة " +
"تُقدَّم فورًا من CDN، بينما الأجزاء الديناميكية تُبثّ " +
"عبر React Suspense.",
metadata: { source: "docs-nextjs" },
},
{
id: "2",
content:
"Mistral AI تقدم نماذج مفتوحة الأوزان مثل Mistral 7B و" +
"Mixtral 8x7B. يمكن نشر هذه النماذج محليًا عبر " +
"Ollama أو vLLM، مما يوفر بديلاً لواجهات API السحابية " +
"للحالات التي تتطلب خصوصية البيانات.",
metadata: { source: "docs-mistral" },
},
{
id: "3",
content:
"استدعاء الدوال في Mistral يسمح للنموذج بتحديد " +
"الدوال التي يجب استدعاؤها تلقائيًا ومع أي معاملات. " +
"هذا يتيح بناء وكلاء ذكاء اصطناعي يتفاعلون مع واجهات " +
"برمجية خارجية وقواعد بيانات وخدمات طرف ثالث.",
metadata: { source: "docs-mistral" },
},
{
id: "4",
content:
"لتحسين تكاليف واجهة Mistral، استخدم التخزين المؤقت " +
"للردود المتكررة، واختر أصغر نموذج مناسب لمهمتك، " +
"وحدّد عدد الرموز الأقصى في الردود. Mistral Small " +
"يكلف حوالي 10 أضعاف أقل من Mistral Large.",
metadata: { source: "guide-optimisation" },
},
]);
const questions = [
"كيف يعمل استدعاء الدوال في Mistral؟",
"ما هو نموذج Mistral الأرخص؟",
"كيف يمكن نشر Mistral محليًا؟",
];
for (const q of questions) {
console.log(`\nالسؤال: ${q}`);
const answer = await rag.query(q);
console.log(`الإجابة: ${answer}`);
}
}
main();الخطوة 8: أفضل ممارسات الإنتاج
معالجة الأخطاء وإعادة المحاولة
// src/utils/resilient-client.ts
import { mistral, MODELS } from "./client";
interface RetryOptions {
maxRetries: number;
baseDelay: number;
maxDelay: number;
}
const DEFAULT_RETRY: RetryOptions = {
maxRetries: 3,
baseDelay: 1000,
maxDelay: 10000,
};
async function withRetry<T>(
fn: () => Promise<T>,
options = DEFAULT_RETRY
): Promise<T> {
let lastError: Error | undefined;
for (let attempt = 0; attempt <= options.maxRetries; attempt++) {
try {
return await fn();
} catch (error: any) {
lastError = error;
if (error.status >= 400 && error.status < 500 && error.status !== 429) {
throw error;
}
if (attempt < options.maxRetries) {
const delay = Math.min(
options.baseDelay * Math.pow(2, attempt),
options.maxDelay
);
console.warn(
`المحاولة ${attempt + 1} فشلت، إعادة المحاولة بعد ${delay}ms...`
);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}
throw lastError;
}
export async function resilientChat(
messages: Array<{ role: string; content: string }>,
model = MODELS.LARGE
) {
return withRetry(() =>
mistral.chat.complete({
model,
messages: messages as any,
})
);
}تتبع التكاليف
// src/utils/cost-tracker.ts
const PRICING = {
"mistral-large-latest": { input: 2.0, output: 6.0 },
"mistral-medium-latest": { input: 0.75, output: 2.25 },
"mistral-small-latest": { input: 0.2, output: 0.6 },
"mistral-embed": { input: 0.1, output: 0 },
} as const;
class CostTracker {
private totalCost = 0;
private calls = 0;
track(model: string, inputTokens: number, outputTokens: number) {
const pricing = PRICING[model as keyof typeof PRICING];
if (!pricing) return;
const cost =
(inputTokens / 1_000_000) * pricing.input +
(outputTokens / 1_000_000) * pricing.output;
this.totalCost += cost;
this.calls++;
return cost;
}
getSummary() {
return {
totalCost: `$${this.totalCost.toFixed(4)}`,
totalCalls: this.calls,
averageCost: `$${(this.totalCost / this.calls).toFixed(4)}`,
};
}
}
export const costTracker = new CostTracker();تحديد المعدل
// src/utils/rate-limiter.ts
class RateLimiter {
private tokens: number;
private lastRefill: number;
private readonly maxTokens: number;
private readonly refillRate: number;
constructor(maxTokens: number, refillRate: number) {
this.maxTokens = maxTokens;
this.tokens = maxTokens;
this.refillRate = refillRate;
this.lastRefill = Date.now();
}
async acquire(): Promise<void> {
this.refill();
if (this.tokens >= 1) {
this.tokens -= 1;
return;
}
const waitTime = (1 / this.refillRate) * 1000;
await new Promise((resolve) => setTimeout(resolve, waitTime));
this.refill();
this.tokens -= 1;
}
private refill() {
const now = Date.now();
const elapsed = (now - this.lastRefill) / 1000;
this.tokens = Math.min(
this.maxTokens,
this.tokens + elapsed * this.refillRate
);
this.lastRefill = now;
}
}
export const apiLimiter = new RateLimiter(5, 5);الخطوة 9: مشروع كامل - مساعد التوثيق
لنجمع كل شيء في مساعد يجيب على أسئلة حول توثيقك:
// src/assistant.ts
import { mistral, MODELS } from "./utils/client";
import { SimpleVectorStore } from "./rag/vector-store";
import { costTracker } from "./utils/cost-tracker";
import fs from "fs";
import path from "path";
class DocumentationAssistant {
private store = new SimpleVectorStore();
async loadDocs(docsDir: string) {
const files = fs
.readdirSync(docsDir)
.filter((f) => f.endsWith(".md"));
const chunks: { id: string; content: string; metadata: Record<string, string> }[] = [];
for (const file of files) {
const content = fs.readFileSync(
path.join(docsDir, file),
"utf-8"
);
const sections = content.split(/^## /m).filter(Boolean);
sections.forEach((section, i) => {
chunks.push({
id: `${file}-${i}`,
content: section.trim().substring(0, 1000),
metadata: { source: file, section: String(i) },
});
});
}
for (let i = 0; i < chunks.length; i += 10) {
const batch = chunks.slice(i, i + 10);
const texts = batch.map((c) => c.content);
const embedResponse = await mistral.embeddings.create({
model: MODELS.EMBED,
inputs: texts,
});
batch.forEach((chunk, j) => {
this.store.add({
...chunk,
embedding: embedResponse.data[j].embedding,
});
});
}
console.log(`تم فهرسة ${chunks.length} مقطع من ${files.length} ملف.`);
}
async answer(question: string): Promise<string> {
const embedResponse = await mistral.embeddings.create({
model: MODELS.EMBED,
inputs: [question],
});
const queryEmbedding = embedResponse.data[0].embedding;
const docs = this.store.search(queryEmbedding, 5);
const context = docs
.map((d) => `المصدر: ${d.metadata.source}\n${d.content}`)
.join("\n\n---\n\n");
const response = await mistral.chat.complete({
model: MODELS.LARGE,
messages: [
{
role: "system",
content:
"أنت مساعد توثيق تقني. " +
"أجب بدقة مع ذكر المصادر. " +
"إذا لم تجد الإجابة في السياق، قل ذلك.\n\n" +
`السياق:\n${context}`,
},
{ role: "user", content: question },
],
temperature: 0.1,
maxTokens: 2048,
});
const usage = response.usage;
if (usage) {
costTracker.track(
MODELS.LARGE,
usage.promptTokens,
usage.completionTokens
);
}
return response.choices?.[0]?.message?.content ?? "لا توجد إجابة";
}
}
export { DocumentationAssistant };استكشاف الأخطاء
الأخطاء الشائعة
| الخطأ | السبب | الحل |
|---|---|---|
401 Unauthorized | مفتاح API غير صالح | تحقق من MISTRAL_API_KEY |
429 Too Many Requests | تم تجاوز حد المعدل | طبّق تحديد المعدل وإعادة المحاولة |
400 Bad Request | تنسيق رسالة غير صالح | تحقق من بنية الرسائل |
| JSON غير صالح في الوضع المنظّم | النموذج أخطأ في التنسيق | قلّل الحرارة، حسّن التوجيه |
| ردود RAG غير متسقة | مقاطع صغيرة أو غير ذات صلة | اضبط حجم المقاطع وعدد النتائج |
تحسين الأداء
- استخدم النموذج المناسب: Mistral Small للتصنيف، Large للتفكير المعقّد
- خزّن التضمينات: لا تعيد حساب تضمينات المستندات التي لم تتغير
- أرسل الطلبات دفعات: استخدم التضمينات بالدُفعات بدلاً من واحدة تلو الأخرى
- حدّد الرموز: اضبط
maxTokensعلى الحد الأدنى المطلوب - البث: استخدم البث للردود الطويلة
الخطوات التالية
- استكشف Codestral لتوليد وإكمال الأكواد
- ادمج Mistral مع LangChain.js لسير عمل معقّد
- انشر مساعدك مع Hono أو Express كـ REST API
- أضف قاعدة بيانات متجهة دائمة مثل Pinecone أو Qdrant
- جرّب الضبط الدقيق لـ Mistral لمجالك
الخلاصة
تعلّمت كيفية استخدام واجهة Mistral AI مع TypeScript لبناء تطبيقات ذكية متكاملة. من المحادثة البسيطة إلى RAG مرورًا باستدعاء الدوال، تقدّم Mistral منظومة غنية وعالية الأداء لدمج الذكاء الاصطناعي في مشاريعك.
تتميّز نماذج Mistral بنسبة جودة/سعر ممتازة ومرونة — سواء اخترت واجهة API السحابية أو النشر المحلي مع النماذج مفتوحة الأوزان. مع أفضل ممارسات الإنتاج (إعادة المحاولة، تحديد المعدل، تتبع التكاليف)، أنت جاهز للنشر بثقة.
ناقش مشروعك معنا
نحن هنا للمساعدة في احتياجات تطوير الويب الخاصة بك. حدد موعدًا لمناقشة مشروعك وكيف يمكننا مساعدتك.
دعنا نجد أفضل الحلول لاحتياجاتك.
مقالات ذات صلة

بناء تطبيقات الذكاء الاصطناعي باستخدام Google Gemini API و TypeScript
تعلّم كيفية بناء تطبيقات ذكاء اصطناعي جاهزة للإنتاج باستخدام Google Gemini API مع TypeScript. يغطي هذا الدليل توليد النصوص، المدخلات متعددة الوسائط، البث المباشر، استدعاء الدوال، والمخرجات المنظمة.

إطار عمل Mastra للذكاء الاصطناعي: بناء وكلاء وسير عمل ذكية بـ TypeScript
تعلم كيفية بناء وكلاء ذكاء اصطناعي وأدوات وسير عمل باستخدام إطار عمل Mastra في TypeScript. يغطي هذا الدليل العملي إنشاء الوكلاء والأدوات المخصصة وسير العمل متعدد الخطوات وأنابيب RAG والنشر.

بناء بوت تيليجرام باستخدام grammY و TypeScript: من الصفر إلى النشر
تعلم كيفية بناء بوت تيليجرام غني بالميزات باستخدام grammY و TypeScript. يغطي هذا الدليل إنشاء البوت والأوامر ولوحات المفاتيح التفاعلية والوسيط والجلسات والنشر في بيئة الإنتاج.