إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
في هذا الدرس، تبني مساعد دردشة تفاعلي يعمل بالكامل على جهازك. المساعد يحافظ على سياق المحادثة عبر عدة تبادلات، لذا يتذكر ما ناقشته سابقا في المحادثة. تستخدم Foundry Local SDK لاختيار نموذج، وتعريف موجه للنظام، وبث الردود رمزا تلو الآخر.
في هذا البرنامج التعليمي، تتعلم كيفية:
- قم بإعداد مشروع وتثبيت حزمة تطوير البرمجيات المحلية للعبة Foundry
- تصفح كتالوج النماذج واختر نموذجا
- تعريف موجه نظام لتشكيل سلوك المساعد
- تنفيذ محادثة متعددة الأدوار مع سجل الرسائل
- استثمر الردود لتجربة سريعة الاستجابة
- نظف الموارد عندما تنتهي المحادثة
المتطلبات المسبقه
- جهاز كمبيوتر يعمل بنظام Windows أو macOS أو Linux يحتوي على ذاكرة RAM لا تقل عن 8 جيجابايت.
مستودع العينات
الكود النموذجي الكامل لهذا المقال متوفر في مستودع Foundry Local GitHub repository. لاستنساخ المستودع والانتقال إلى العينة، استخدم:
git clone https://github.com/microsoft/Foundry-Local.git
cd Foundry-Local/samples/cs/tutorial-chat-assistant
تثبيت الحزم
إذا كنت تطور أو تشحن على Windows، اختر تبويب Windows. تتكامل حزمة Windows مع وقت التشغيل Windows ML — حيث توفر نفس مساحة واجهة برمجة التطبيقات مع تسريع أوسع في الأجهزة.
dotnet add package Microsoft.AI.Foundry.Local.WinML
dotnet add package OpenAI
عينات C# في مستودع GitHub هي مشاريع مهيأة مسبقا. إذا كنت تبني من الصفر، يجب عليك قراءة مرجع Foundry Local SDK لمزيد من التفاصيل حول كيفية إعداد مشروع C# الخاص بك مع Foundry Local.
تصفح الكتالوج واختر عارضا
يوفر دليل تطوير النماذج المحلي للفاوندري كتالوج نماذج يسرد جميع النماذج المتاحة. في هذه الخطوة، تقوم بتهيئة مجموعة تطوير البرمجيات واختيار نموذج لمساعد الدردشة الخاص بك.
افتح
Program.csواستبدل محتوياته بالرمز التالي لتهيئة مجموعة تطوير البرمجيات واختيار نموذج:CancellationToken ct = CancellationToken.None; var config = new Configuration { AppName = "foundry_local_samples", LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information }; using var loggerFactory = LoggerFactory.Create(builder => { builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information); }); var logger = loggerFactory.CreateLogger<Program>(); // Initialize the singleton instance await FoundryLocalManager.CreateAsync(config, logger); var mgr = FoundryLocalManager.Instance; // Download and register all execution providers. var currentEp = ""; await mgr.DownloadAndRegisterEpsAsync((epName, percent) => { if (epName != currentEp) { if (currentEp != "") Console.WriteLine(); currentEp = epName; } Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); }); if (currentEp != "") Console.WriteLine(); // Select and load a model from the catalog var catalog = await mgr.GetCatalogAsync(); var model = await catalog.GetModelAsync("qwen2.5-0.5b") ?? throw new Exception("Model not found"); await model.DownloadAsync(progress => { Console.Write($"\rDownloading model: {progress:F2}%"); if (progress >= 100f) Console.WriteLine(); }); await model.LoadAsync(); Console.WriteLine("Model loaded and ready."); // Get a chat client var chatClient = await model.GetChatClientAsync();GetModelAsyncتقبل الطريقة اسم مستعار للنموذج، وهو اسم ودود قصير يربط بنموذج معين في الكتالوج. تقوم الطريقةDownloadAsyncبجلب أوزان النماذج إلى ذاكرة التخزين المؤقت المحلية لديك، وتجعلLoadAsyncالنموذج جاهزا للاستنتاج.
تعريف موجه نظام
تحدد تعليمات النظام شخصية وسلوك المساعد. إنها الرسالة الأولى في سجل المحادثة والنموذج يشير إليها طوال المحادثة.
أضف تنبيه نظام لتشكيل كيفية استجابة المساعد:
// Start the conversation with a system prompt
var messages = new List<ChatMessage>
{
new ChatMessage
{
Role = "system",
Content = "You are a helpful, friendly assistant. Keep your responses " +
"concise and conversational. If you don't know something, say so."
}
};
نصيحة
جرب تعليمات النظام المختلفة لتغيير سلوك المساعد. على سبيل المثال، يمكنك توجيهه للاستجابة كقرصان أو معلم أو خبير في المجال.
تنفيذ محادثة متعددة الأدوار
يحتاج مساعد الدردشة إلى الحفاظ على السياق عبر عدة تبادلات. تحقق ذلك من خلال الاحتفاظ بقائمة بجميع الرسائل (النظام، المستخدم، والمساعد) وإرسال القائمة الكاملة مع كل طلب. يستخدم النموذج هذا التاريخ لتوليد ردود ذات صلة بالسياق.
أضف حلقة محادثة تقول:
- يقرأ مدخلات المستخدم من وحدة التحكم.
- يرفق رسالة المستخدم إلى السجل التاريخي.
- يرسل التاريخ الكامل إلى النموذج.
- يرفق رد المساعد إلى السجل للدور التالي.
while (true)
{
Console.Write("You: ");
var userInput = Console.ReadLine();
if (string.IsNullOrWhiteSpace(userInput) ||
userInput.Equals("quit", StringComparison.OrdinalIgnoreCase) ||
userInput.Equals("exit", StringComparison.OrdinalIgnoreCase))
{
break;
}
// Add the user's message to conversation history
messages.Add(new ChatMessage { Role = "user", Content = userInput });
// Stream the response token by token
Console.Write("Assistant: ");
var fullResponse = string.Empty;
var streamingResponse = chatClient.CompleteChatStreamingAsync(messages, ct);
await foreach (var chunk in streamingResponse)
{
var content = chunk.Choices[0].Message.Content;
if (!string.IsNullOrEmpty(content))
{
Console.Write(content);
Console.Out.Flush();
fullResponse += content;
}
}
Console.WriteLine("\n");
// Add the complete response to conversation history
messages.Add(new ChatMessage { Role = "assistant", Content = fullResponse });
}
كل مكالمة تتلقى CompleteChatAsync سجل الرسائل الكامل. هكذا "يتذكر" النموذج الأدوار السابقة — لا يخزن الحالة بين المكالمات.
أضف ردود البث
البث يطبع كل رمز أثناء تولده، مما يجعل المساعد أكثر استجابة. استبدل المكالمة CompleteChatAsync ب CompleteChatStreamingAsync لبث رمز الاستجابة برمز.
قم بتحديث حلقة المحادثة لاستخدام البث:
// Stream the response token by token
Console.Write("Assistant: ");
var fullResponse = string.Empty;
var streamingResponse = chatClient.CompleteChatStreamingAsync(messages, ct);
await foreach (var chunk in streamingResponse)
{
var content = chunk.Choices[0].Message.Content;
if (!string.IsNullOrEmpty(content))
{
Console.Write(content);
Console.Out.Flush();
fullResponse += content;
}
}
Console.WriteLine("\n");
تقوم نسخة البث بجمع الرد الكامل بحيث يمكن إضافتها إلى سجل المحادثة بعد انتهاء البث.
تعليمة برمجية كاملة
استبدل محتوى الرمز Program.cs الكامل التالي:
using Microsoft.AI.Foundry.Local;
using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels;
using Microsoft.Extensions.Logging;
CancellationToken ct = CancellationToken.None;
var config = new Configuration
{
AppName = "foundry_local_samples",
LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information
};
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information);
});
var logger = loggerFactory.CreateLogger<Program>();
// Initialize the singleton instance
await FoundryLocalManager.CreateAsync(config, logger);
var mgr = FoundryLocalManager.Instance;
// Download and register all execution providers.
var currentEp = "";
await mgr.DownloadAndRegisterEpsAsync((epName, percent) =>
{
if (epName != currentEp)
{
if (currentEp != "") Console.WriteLine();
currentEp = epName;
}
Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%");
});
if (currentEp != "") Console.WriteLine();
// Select and load a model from the catalog
var catalog = await mgr.GetCatalogAsync();
var model = await catalog.GetModelAsync("qwen2.5-0.5b")
?? throw new Exception("Model not found");
await model.DownloadAsync(progress =>
{
Console.Write($"\rDownloading model: {progress:F2}%");
if (progress >= 100f) Console.WriteLine();
});
await model.LoadAsync();
Console.WriteLine("Model loaded and ready.");
// Get a chat client
var chatClient = await model.GetChatClientAsync();
// Start the conversation with a system prompt
var messages = new List<ChatMessage>
{
new ChatMessage
{
Role = "system",
Content = "You are a helpful, friendly assistant. Keep your responses " +
"concise and conversational. If you don't know something, say so."
}
};
Console.WriteLine("\nChat assistant ready! Type 'quit' to exit.\n");
while (true)
{
Console.Write("You: ");
var userInput = Console.ReadLine();
if (string.IsNullOrWhiteSpace(userInput) ||
userInput.Equals("quit", StringComparison.OrdinalIgnoreCase) ||
userInput.Equals("exit", StringComparison.OrdinalIgnoreCase))
{
break;
}
// Add the user's message to conversation history
messages.Add(new ChatMessage { Role = "user", Content = userInput });
// Stream the response token by token
Console.Write("Assistant: ");
var fullResponse = string.Empty;
var streamingResponse = chatClient.CompleteChatStreamingAsync(messages, ct);
await foreach (var chunk in streamingResponse)
{
var content = chunk.Choices[0].Message.Content;
if (!string.IsNullOrEmpty(content))
{
Console.Write(content);
Console.Out.Flush();
fullResponse += content;
}
}
Console.WriteLine("\n");
// Add the complete response to conversation history
messages.Add(new ChatMessage { Role = "assistant", Content = fullResponse });
}
// Clean up - unload the model
await model.UnloadAsync();
Console.WriteLine("Model unloaded. Goodbye!");
شغل مساعد الدردشة:
dotnet run
ترى مخرجا مشابها ل:
Downloading model: 100.00%
Model loaded and ready.
Chat assistant ready! Type 'quit' to exit.
You: What is photosynthesis?
Assistant: Photosynthesis is the process plants use to convert sunlight, water, and carbon
dioxide into glucose and oxygen. It mainly happens in the leaves, inside structures
called chloroplasts.
You: Why is it important for other living things?
Assistant: It's essential because photosynthesis produces the oxygen that most living things
breathe. It also forms the base of the food chain — animals eat plants or eat other
animals that depend on plants for energy.
You: quit
Model unloaded. Goodbye!
لاحظ كيف يتذكر المساعد السياق من الأدوار السابقة — عندما تسأل "لماذا هو مهم للكائنات الحية الأخرى؟"، يعلم أنك لا تزال تتحدث عن التمثيل الضوئي.
مستودع العينات
الكود النموذجي الكامل لهذا المقال متوفر في مستودع Foundry Local GitHub repository. لاستنساخ المستودع والانتقال إلى العينة، استخدم:
git clone https://github.com/microsoft/Foundry-Local.git
cd Foundry-Local/samples/js/tutorial-chat-assistant
تثبيت الحزم
إذا كنت تطور أو تشحن على Windows، اختر تبويب Windows. تتكامل حزمة Windows مع وقت التشغيل Windows ML — حيث توفر نفس مساحة واجهة برمجة التطبيقات مع تسريع أوسع في الأجهزة.
npm install foundry-local-sdk-winml openai
تصفح الكتالوج واختر عارضا
يوفر دليل تطوير النماذج المحلي للفاوندري كتالوج نماذج يسرد جميع النماذج المتاحة. في هذه الخطوة، تقوم بتهيئة مجموعة تطوير البرمجيات واختيار نموذج لمساعد الدردشة الخاص بك.
أنشئ ملفا يسمى
index.js.أضف الكود التالي لتهيئة مجموعة تطوير البرمجيات واختيار نموذج:
// Initialize the Foundry Local SDK const manager = FoundryLocalManager.create({ appName: 'foundry_local_samples', logLevel: 'info' }); // Download and register all execution providers. let currentEp = ''; await manager.downloadAndRegisterEps((epName, percent) => { if (epName !== currentEp) { if (currentEp !== '') process.stdout.write('\n'); currentEp = epName; } process.stdout.write(`\r ${epName.padEnd(30)} ${percent.toFixed(1).padStart(5)}%`); }); if (currentEp !== '') process.stdout.write('\n'); // Select and load a model from the catalog const model = await manager.catalog.getModel('qwen2.5-0.5b'); await model.download((progress) => { process.stdout.write(`\rDownloading model: ${progress.toFixed(2)}%`); }); console.log('\nModel downloaded.'); await model.load(); console.log('Model loaded and ready.'); // Create a chat client const chatClient = model.createChatClient();getModelتقبل الطريقة اسم مستعار للنموذج، وهو اسم ودود قصير يربط بنموذج معين في الكتالوج. تقوم الطريقةdownloadبجلب أوزان النماذج إلى ذاكرة التخزين المؤقت المحلية لديك، وتجعلloadالنموذج جاهزا للاستنتاج.
تعريف موجه نظام
تحدد تعليمات النظام شخصية وسلوك المساعد. إنها الرسالة الأولى في سجل المحادثة والنموذج يشير إليها طوال المحادثة.
أضف تنبيه نظام لتشكيل كيفية استجابة المساعد:
// Start the conversation with a system prompt
const messages = [
{
role: 'system',
content: 'You are a helpful, friendly assistant. Keep your responses ' +
'concise and conversational. If you don\'t know something, say so.'
}
];
نصيحة
جرب تعليمات النظام المختلفة لتغيير سلوك المساعد. على سبيل المثال، يمكنك توجيهه للاستجابة كقرصان أو معلم أو خبير في المجال.
تنفيذ محادثة متعددة الأدوار
يحتاج مساعد الدردشة إلى الحفاظ على السياق عبر عدة تبادلات. تحقق ذلك من خلال الاحتفاظ بقائمة بجميع الرسائل (النظام، المستخدم، والمساعد) وإرسال القائمة الكاملة مع كل طلب. يستخدم النموذج هذا التاريخ لتوليد ردود ذات صلة بالسياق.
أضف حلقة محادثة تقول:
- يقرأ مدخلات المستخدم من وحدة التحكم.
- يرفق رسالة المستخدم إلى السجل التاريخي.
- يرسل التاريخ الكامل إلى النموذج.
- يرفق رد المساعد إلى السجل للدور التالي.
while (true) {
const userInput = await askQuestion('You: ');
if (userInput.trim().toLowerCase() === 'quit' ||
userInput.trim().toLowerCase() === 'exit') {
break;
}
// Add the user's message to conversation history
messages.push({ role: 'user', content: userInput });
// Stream the response token by token
process.stdout.write('Assistant: ');
let fullResponse = '';
for await (const chunk of chatClient.completeStreamingChat(messages)) {
const content = chunk.choices?.[0]?.delta?.content;
if (content) {
process.stdout.write(content);
fullResponse += content;
}
}
console.log('\n');
// Add the complete response to conversation history
messages.push({ role: 'assistant', content: fullResponse });
}
كل مكالمة تتلقى completeChat سجل الرسائل الكامل. هكذا "يتذكر" النموذج الأدوار السابقة — لا يخزن الحالة بين المكالمات.
أضف ردود البث
البث يطبع كل رمز أثناء تولده، مما يجعل المساعد أكثر استجابة. استبدل المكالمة completeChat ب completeStreamingChat لبث رمز الاستجابة برمز.
قم بتحديث حلقة المحادثة لاستخدام البث:
// Stream the response token by token
process.stdout.write('Assistant: ');
let fullResponse = '';
for await (const chunk of chatClient.completeStreamingChat(messages)) {
const content = chunk.choices?.[0]?.delta?.content;
if (content) {
process.stdout.write(content);
fullResponse += content;
}
}
console.log('\n');
تقوم نسخة البث بجمع الرد الكامل بحيث يمكن إضافتها إلى سجل المحادثة بعد انتهاء البث.
تعليمة برمجية كاملة
أنشئ ملفا مسمى index.js وأضف الكود الكامل التالي:
import { FoundryLocalManager } from 'foundry-local-sdk';
import * as readline from 'readline';
// Initialize the Foundry Local SDK
const manager = FoundryLocalManager.create({
appName: 'foundry_local_samples',
logLevel: 'info'
});
// Download and register all execution providers.
let currentEp = '';
await manager.downloadAndRegisterEps((epName, percent) => {
if (epName !== currentEp) {
if (currentEp !== '') process.stdout.write('\n');
currentEp = epName;
}
process.stdout.write(`\r ${epName.padEnd(30)} ${percent.toFixed(1).padStart(5)}%`);
});
if (currentEp !== '') process.stdout.write('\n');
// Select and load a model from the catalog
const model = await manager.catalog.getModel('qwen2.5-0.5b');
await model.download((progress) => {
process.stdout.write(`\rDownloading model: ${progress.toFixed(2)}%`);
});
console.log('\nModel downloaded.');
await model.load();
console.log('Model loaded and ready.');
// Create a chat client
const chatClient = model.createChatClient();
// Start the conversation with a system prompt
const messages = [
{
role: 'system',
content: 'You are a helpful, friendly assistant. Keep your responses ' +
'concise and conversational. If you don\'t know something, say so.'
}
];
// Set up readline for console input
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const askQuestion = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
console.log('\nChat assistant ready! Type \'quit\' to exit.\n');
while (true) {
const userInput = await askQuestion('You: ');
if (userInput.trim().toLowerCase() === 'quit' ||
userInput.trim().toLowerCase() === 'exit') {
break;
}
// Add the user's message to conversation history
messages.push({ role: 'user', content: userInput });
// Stream the response token by token
process.stdout.write('Assistant: ');
let fullResponse = '';
for await (const chunk of chatClient.completeStreamingChat(messages)) {
const content = chunk.choices?.[0]?.delta?.content;
if (content) {
process.stdout.write(content);
fullResponse += content;
}
}
console.log('\n');
// Add the complete response to conversation history
messages.push({ role: 'assistant', content: fullResponse });
}
// Clean up - unload the model
await model.unload();
console.log('Model unloaded. Goodbye!');
rl.close();
شغل مساعد الدردشة:
node index.js
ترى مخرجا مشابها ل:
Downloading model: 100.00%
Model downloaded.
Model loaded and ready.
Chat assistant ready! Type 'quit' to exit.
You: What is photosynthesis?
Assistant: Photosynthesis is the process plants use to convert sunlight, water, and carbon
dioxide into glucose and oxygen. It mainly happens in the leaves, inside structures
called chloroplasts.
You: Why is it important for other living things?
Assistant: It's essential because photosynthesis produces the oxygen that most living things
breathe. It also forms the base of the food chain — animals eat plants or eat other
animals that depend on plants for energy.
You: quit
Model unloaded. Goodbye!
لاحظ كيف يتذكر المساعد السياق من الأدوار السابقة — عندما تسأل "لماذا هو مهم للكائنات الحية الأخرى؟"، يعلم أنك لا تزال تتحدث عن التمثيل الضوئي.
مستودع العينات
الكود النموذجي الكامل لهذا المقال متوفر في مستودع Foundry Local GitHub repository. لاستنساخ المستودع والانتقال إلى العينة، استخدم:
git clone https://github.com/microsoft/Foundry-Local.git
cd Foundry-Local/samples/python/tutorial-chat-assistant
تثبيت الحزم
إذا كنت تطور أو تشحن على Windows، اختر تبويب Windows. تتكامل حزمة Windows مع وقت التشغيل Windows ML — حيث توفر نفس مساحة واجهة برمجة التطبيقات مع تسريع أوسع في الأجهزة.
pip install foundry-local-sdk-winml openai
تصفح الكتالوج واختر عارضا
يوفر دليل تطوير النماذج المحلي للفاوندري كتالوج نماذج يسرد جميع النماذج المتاحة. في هذه الخطوة، تقوم بتهيئة مجموعة تطوير البرمجيات واختيار نموذج لمساعد الدردشة الخاص بك.
أنشئ ملفا يسمى
main.py.أضف الكود التالي لتهيئة مجموعة تطوير البرمجيات واختيار نموذج:
# Initialize the Foundry Local SDK config = Configuration(app_name="foundry_local_samples") FoundryLocalManager.initialize(config) manager = FoundryLocalManager.instance # Download and register all execution providers. current_ep = "" def ep_progress(ep_name: str, percent: float): nonlocal current_ep if ep_name != current_ep: if current_ep: print() current_ep = ep_name print(f"\r {ep_name:<30} {percent:5.1f}%", end="", flush=True) manager.download_and_register_eps(progress_callback=ep_progress) if current_ep: print() # Select and load a model from the catalog model = manager.catalog.get_model("qwen2.5-0.5b") model.download(lambda progress: print(f"\rDownloading model: {progress:.2f}%", end="", flush=True)) print() model.load() print("Model loaded and ready.") # Get a chat client client = model.get_chat_client()get_modelتقبل الطريقة اسم مستعار للنموذج، وهو اسم ودود قصير يربط بنموذج معين في الكتالوج. تقوم الطريقةdownloadبجلب أوزان النماذج إلى ذاكرة التخزين المؤقت المحلية لديك، وتجعلloadالنموذج جاهزا للاستنتاج.
تعريف موجه نظام
تحدد تعليمات النظام شخصية وسلوك المساعد. إنها الرسالة الأولى في سجل المحادثة والنموذج يشير إليها طوال المحادثة.
أضف تنبيه نظام لتشكيل كيفية استجابة المساعد:
# Start the conversation with a system prompt
messages = [
{
"role": "system",
"content": "You are a helpful, friendly assistant. Keep your responses "
"concise and conversational. If you don't know something, say so."
}
]
نصيحة
جرب تعليمات النظام المختلفة لتغيير سلوك المساعد. على سبيل المثال، يمكنك توجيهه للاستجابة كقرصان أو معلم أو خبير في المجال.
تنفيذ محادثة متعددة الأدوار
يحتاج مساعد الدردشة إلى الحفاظ على السياق عبر عدة تبادلات. تحقق ذلك من خلال الاحتفاظ بقائمة بجميع الرسائل (النظام، المستخدم، والمساعد) وإرسال القائمة الكاملة مع كل طلب. يستخدم النموذج هذا التاريخ لتوليد ردود ذات صلة بالسياق.
أضف حلقة محادثة تقول:
- يقرأ مدخلات المستخدم من وحدة التحكم.
- يرفق رسالة المستخدم إلى السجل التاريخي.
- يرسل التاريخ الكامل إلى النموذج.
- يرفق رد المساعد إلى السجل للدور التالي.
while True:
user_input = input("You: ")
if user_input.strip().lower() in ("quit", "exit"):
break
# Add the user's message to conversation history
messages.append({"role": "user", "content": user_input})
# Stream the response token by token
print("Assistant: ", end="", flush=True)
full_response = ""
for chunk in client.complete_streaming_chat(messages):
content = chunk.choices[0].delta.content
if content:
print(content, end="", flush=True)
full_response += content
print("\n")
# Add the complete response to conversation history
messages.append({"role": "assistant", "content": full_response})
كل مكالمة تتلقى complete_chat سجل الرسائل الكامل. هكذا "يتذكر" النموذج الأدوار السابقة — لا يخزن الحالة بين المكالمات.
أضف ردود البث
البث يطبع كل رمز أثناء تولده، مما يجعل المساعد أكثر استجابة. استبدل المكالمة complete_chat ب complete_streaming_chat لبث رمز الاستجابة برمز.
قم بتحديث حلقة المحادثة لاستخدام البث:
# Stream the response token by token
print("Assistant: ", end="", flush=True)
full_response = ""
for chunk in client.complete_streaming_chat(messages):
content = chunk.choices[0].delta.content
if content:
print(content, end="", flush=True)
full_response += content
print("\n")
تقوم نسخة البث بجمع الرد الكامل بحيث يمكن إضافتها إلى سجل المحادثة بعد انتهاء البث.
تعليمة برمجية كاملة
أنشئ ملفا مسمى main.py وأضف الكود الكامل التالي:
from foundry_local_sdk import Configuration, FoundryLocalManager
def main():
# Initialize the Foundry Local SDK
config = Configuration(app_name="foundry_local_samples")
FoundryLocalManager.initialize(config)
manager = FoundryLocalManager.instance
# Download and register all execution providers.
current_ep = ""
def ep_progress(ep_name: str, percent: float):
nonlocal current_ep
if ep_name != current_ep:
if current_ep:
print()
current_ep = ep_name
print(f"\r {ep_name:<30} {percent:5.1f}%", end="", flush=True)
manager.download_and_register_eps(progress_callback=ep_progress)
if current_ep:
print()
# Select and load a model from the catalog
model = manager.catalog.get_model("qwen2.5-0.5b")
model.download(lambda progress: print(f"\rDownloading model: {progress:.2f}%", end="", flush=True))
print()
model.load()
print("Model loaded and ready.")
# Get a chat client
client = model.get_chat_client()
# Start the conversation with a system prompt
messages = [
{
"role": "system",
"content": "You are a helpful, friendly assistant. Keep your responses "
"concise and conversational. If you don't know something, say so."
}
]
print("\nChat assistant ready! Type 'quit' to exit.\n")
while True:
user_input = input("You: ")
if user_input.strip().lower() in ("quit", "exit"):
break
# Add the user's message to conversation history
messages.append({"role": "user", "content": user_input})
# Stream the response token by token
print("Assistant: ", end="", flush=True)
full_response = ""
for chunk in client.complete_streaming_chat(messages):
content = chunk.choices[0].delta.content
if content:
print(content, end="", flush=True)
full_response += content
print("\n")
# Add the complete response to conversation history
messages.append({"role": "assistant", "content": full_response})
# Clean up - unload the model
model.unload()
print("Model unloaded. Goodbye!")
if __name__ == "__main__":
main()
شغل مساعد الدردشة:
python main.py
ترى مخرجا مشابها ل:
Downloading model: 100.00%
Model loaded and ready.
Chat assistant ready! Type 'quit' to exit.
You: What is photosynthesis?
Assistant: Photosynthesis is the process plants use to convert sunlight, water, and carbon
dioxide into glucose and oxygen. It mainly happens in the leaves, inside structures
called chloroplasts.
You: Why is it important for other living things?
Assistant: It's essential because photosynthesis produces the oxygen that most living things
breathe. It also forms the base of the food chain — animals eat plants or eat other
animals that depend on plants for energy.
You: quit
Model unloaded. Goodbye!
لاحظ كيف يتذكر المساعد السياق من الأدوار السابقة — عندما تسأل "لماذا هو مهم للكائنات الحية الأخرى؟"، يعلم أنك لا تزال تتحدث عن التمثيل الضوئي.
مستودع العينات
الكود النموذجي الكامل لهذا المقال متوفر في مستودع Foundry Local GitHub repository. لاستنساخ المستودع والانتقال إلى العينة، استخدم:
git clone https://github.com/microsoft/Foundry-Local.git
cd Foundry-Local/samples/rust/tutorial-chat-assistant
تثبيت الحزم
إذا كنت تطور أو تشحن على Windows، اختر تبويب Windows. تتكامل حزمة Windows مع وقت التشغيل Windows ML — حيث توفر نفس مساحة واجهة برمجة التطبيقات مع تسريع أوسع في الأجهزة.
cargo add foundry-local-sdk --features winml
cargo add tokio --features full
cargo add tokio-stream anyhow
تصفح الكتالوج واختر عارضا
يوفر دليل تطوير النماذج المحلي للفاوندري كتالوج نماذج يسرد جميع النماذج المتاحة. في هذه الخطوة، تقوم بتهيئة مجموعة تطوير البرمجيات واختيار نموذج لمساعد الدردشة الخاص بك.
افتح
src/main.rsواستبدل محتوياته بالرمز التالي لتهيئة مجموعة تطوير البرمجيات واختيار نموذج:// Initialize the Foundry Local SDK let manager = FoundryLocalManager::create(FoundryLocalConfig::new("chat-assistant"))?; // Download and register all execution providers. manager .download_and_register_eps_with_progress(None, { let mut current_ep = String::new(); move |ep_name: &str, percent: f64| { if ep_name != current_ep { if !current_ep.is_empty() { println!(); } current_ep = ep_name.to_string(); } print!("\r {:<30} {:5.1}%", ep_name, percent); io::stdout().flush().ok(); } }) .await?; println!(); // Select and load a model from the catalog let model = manager.catalog().get_model("qwen2.5-0.5b").await?; if !model.is_cached().await? { println!("Downloading model..."); model .download(Some(|progress: f64| { print!("\r {progress:.1}%"); io::stdout().flush().ok(); })) .await?; println!(); } model.load().await?; println!("Model loaded and ready."); // Create a chat client let client = model.create_chat_client().temperature(0.7).max_tokens(512);get_modelتقبل الطريقة اسم مستعار للنموذج، وهو اسم ودود قصير يربط بنموذج معين في الكتالوج. تقوم الطريقةdownloadبجلب أوزان النماذج إلى ذاكرة التخزين المؤقت المحلية لديك، وتجعلloadالنموذج جاهزا للاستنتاج.
تعريف موجه نظام
تحدد تعليمات النظام شخصية وسلوك المساعد. إنها الرسالة الأولى في سجل المحادثة والنموذج يشير إليها طوال المحادثة.
أضف تنبيه نظام لتشكيل كيفية استجابة المساعد:
// Start the conversation with a system prompt
let mut messages: Vec<ChatCompletionRequestMessage> = vec![
ChatCompletionRequestSystemMessage::from(
"You are a helpful, friendly assistant. Keep your responses \
concise and conversational. If you don't know something, say so.",
)
.into(),
];
نصيحة
جرب تعليمات النظام المختلفة لتغيير سلوك المساعد. على سبيل المثال، يمكنك توجيهه للاستجابة كقرصان أو معلم أو خبير في المجال.
تنفيذ محادثة متعددة الأدوار
يحتاج مساعد الدردشة إلى الحفاظ على السياق عبر عدة تبادلات. تحقق ذلك من خلال الاحتفاظ بمتجه لجميع الرسائل (النظام، المستخدم، والمساعد) وإرسال القائمة الكاملة مع كل طلب. يستخدم النموذج هذا التاريخ لتوليد ردود ذات صلة بالسياق.
أضف حلقة محادثة تقول:
- يقرأ مدخلات المستخدم من وحدة التحكم.
- يرفق رسالة المستخدم إلى السجل التاريخي.
- يرسل التاريخ الكامل إلى النموذج.
- يرفق رد المساعد إلى السجل للدور التالي.
loop {
print!("You: ");
io::stdout().flush()?;
let mut input = String::new();
stdin.lock().read_line(&mut input)?;
let input = input.trim();
if input.eq_ignore_ascii_case("quit") || input.eq_ignore_ascii_case("exit") {
break;
}
// Add the user's message to conversation history
messages.push(ChatCompletionRequestUserMessage::from(input).into());
// Stream the response token by token
print!("Assistant: ");
io::stdout().flush()?;
let mut full_response = String::new();
let mut stream = client.complete_streaming_chat(&messages, None).await?;
while let Some(chunk) = stream.next().await {
let chunk = chunk?;
if let Some(choice) = chunk.choices.first() {
if let Some(ref content) = choice.delta.content {
print!("{content}");
io::stdout().flush()?;
full_response.push_str(content);
}
}
}
println!("\n");
// Add the complete response to conversation history
let assistant_msg: ChatCompletionRequestMessage = serde_json::from_value(
serde_json::json!({"role": "assistant", "content": full_response}),
)?;
messages.push(assistant_msg);
}
كل مكالمة تتلقى complete_chat سجل الرسائل الكامل. هكذا "يتذكر" النموذج الأدوار السابقة — لا يخزن الحالة بين المكالمات.
أضف ردود البث
البث يطبع كل رمز أثناء تولده، مما يجعل المساعد أكثر استجابة. استبدل المكالمة complete_chat ب complete_streaming_chat لبث رمز الاستجابة برمز.
قم بتحديث حلقة المحادثة لاستخدام البث:
// Stream the response token by token
print!("Assistant: ");
io::stdout().flush()?;
let mut full_response = String::new();
let mut stream = client.complete_streaming_chat(&messages, None).await?;
while let Some(chunk) = stream.next().await {
let chunk = chunk?;
if let Some(choice) = chunk.choices.first() {
if let Some(ref content) = choice.delta.content {
print!("{content}");
io::stdout().flush()?;
full_response.push_str(content);
}
}
}
println!("\n");
تقوم نسخة البث بجمع الرد الكامل بحيث يمكن إضافتها إلى سجل المحادثة بعد انتهاء البث.
تعليمة برمجية كاملة
استبدل محتوى الرمز src/main.rs الكامل التالي:
use foundry_local_sdk::{
ChatCompletionRequestMessage,
ChatCompletionRequestSystemMessage, ChatCompletionRequestUserMessage,
FoundryLocalConfig, FoundryLocalManager,
};
use std::io::{self, BufRead, Write};
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Initialize the Foundry Local SDK
let manager = FoundryLocalManager::create(FoundryLocalConfig::new("chat-assistant"))?;
// Download and register all execution providers.
manager
.download_and_register_eps_with_progress(None, {
let mut current_ep = String::new();
move |ep_name: &str, percent: f64| {
if ep_name != current_ep {
if !current_ep.is_empty() {
println!();
}
current_ep = ep_name.to_string();
}
print!("\r {:<30} {:5.1}%", ep_name, percent);
io::stdout().flush().ok();
}
})
.await?;
println!();
// Select and load a model from the catalog
let model = manager.catalog().get_model("qwen2.5-0.5b").await?;
if !model.is_cached().await? {
println!("Downloading model...");
model
.download(Some(|progress: f64| {
print!("\r {progress:.1}%");
io::stdout().flush().ok();
}))
.await?;
println!();
}
model.load().await?;
println!("Model loaded and ready.");
// Create a chat client
let client = model.create_chat_client().temperature(0.7).max_tokens(512);
// Start the conversation with a system prompt
let mut messages: Vec<ChatCompletionRequestMessage> = vec![
ChatCompletionRequestSystemMessage::from(
"You are a helpful, friendly assistant. Keep your responses \
concise and conversational. If you don't know something, say so.",
)
.into(),
];
println!("\nChat assistant ready! Type 'quit' to exit.\n");
let stdin = io::stdin();
loop {
print!("You: ");
io::stdout().flush()?;
let mut input = String::new();
stdin.lock().read_line(&mut input)?;
let input = input.trim();
if input.eq_ignore_ascii_case("quit") || input.eq_ignore_ascii_case("exit") {
break;
}
// Add the user's message to conversation history
messages.push(ChatCompletionRequestUserMessage::from(input).into());
// Stream the response token by token
print!("Assistant: ");
io::stdout().flush()?;
let mut full_response = String::new();
let mut stream = client.complete_streaming_chat(&messages, None).await?;
while let Some(chunk) = stream.next().await {
let chunk = chunk?;
if let Some(choice) = chunk.choices.first() {
if let Some(ref content) = choice.delta.content {
print!("{content}");
io::stdout().flush()?;
full_response.push_str(content);
}
}
}
println!("\n");
// Add the complete response to conversation history
let assistant_msg: ChatCompletionRequestMessage = serde_json::from_value(
serde_json::json!({"role": "assistant", "content": full_response}),
)?;
messages.push(assistant_msg);
}
// Clean up - unload the model
model.unload().await?;
println!("Model unloaded. Goodbye!");
Ok(())
}
شغل مساعد الدردشة:
cargo run
ترى مخرجا مشابها ل:
Downloading model: 100.00%
Model loaded and ready.
Chat assistant ready! Type 'quit' to exit.
You: What is photosynthesis?
Assistant: Photosynthesis is the process plants use to convert sunlight, water, and carbon
dioxide into glucose and oxygen. It mainly happens in the leaves, inside structures
called chloroplasts.
You: Why is it important for other living things?
Assistant: It's essential because photosynthesis produces the oxygen that most living things
breathe. It also forms the base of the food chain — animals eat plants or eat other
animals that depend on plants for energy.
You: quit
Model unloaded. Goodbye!
لاحظ كيف يتذكر المساعد السياق من الأدوار السابقة — عندما تسأل "لماذا هو مهم للكائنات الحية الأخرى؟"، يعلم أنك لا تزال تتحدث عن التمثيل الضوئي.
تنظيف الموارد
أوزان النماذج تبقى في ذاكرة التخزين المؤقت المحلية بعد تفريغ النموذج. هذا يعني أنه في المرة القادمة التي تشغل فيها التطبيق، يتم تخطي خطوة التحميل ويتم تحميل النموذج بشكل أسرع. لا حاجة لتنظيف إضافي إلا إذا أردت استعادة مساحة القرص.