إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
يدعم Microsoft Agent Framework استرداد الجيل المعزز (RAG) من خلال موفري السياق الذين يضيفون المحتوى الذي تم استرداده قبل استدعاء النموذج وأدوات البحث التي تسمح للنموذج باسترداد بيانات الأساس عند الطلب.
للحصول على أنماط المحادثة/الجلسة إلى جانب الاسترداد، راجع نظرة عامة على المحادثات والذاكرة. للإعداد الخاص بالخدمة، راجع البحث باستخدام الذكاء الاصطناعي في AzureMicrosoft FoundryوNeo4j.
استخدام TextSearchProvider
TextSearchProvider الفئة هي تنفيذ خارج الصندوق لموفر سياق RAG.
وهو يدعم أوضاعا مختلفة من التشغيل، على سبيل المثال إجراء بحث عن كل وكيل يتم تشغيله باستخدام محفوظات الدردشة، أو أدوات وظيفة الإعلان لإجراء عمليات البحث.
يمكن إرفاقه ChatClientAgent بسهولة باستخدام AIContextProviders الخيار .
// Configure the options for the TextSearchProvider.
TextSearchProviderOptions textSearchOptions = new()
{
SearchTime = TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke,
};
// Create the AI agent with the TextSearchProvider.
AIAgent agent = azureOpenAIClient
.GetChatClient(deploymentName)
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are a helpful support specialist. Answer questions using the provided context and cite the source document when available." },
AIContextProviders = [new TextSearchProvider(SearchAdapter, textSearchOptions)]
});
TextSearchProvider يتطلب دالة توفر نتائج البحث مع إعطاء استعلام. يمكن تنفيذ ذلك باستخدام أي تقنية بحث، على سبيل المثال، البحث باستخدام الذكاء الاصطناعي في Azure أو محرك بحث ويب.
Tip
راجع تكاملات مخزن المتجهات لمزيد من المعلومات حول كيفية استخدام مخزن متجهات لنتائج البحث.
فيما يلي مثال على دالة بحث وهمية ترجع نتائج معرفة مسبقا استنادا إلى الاستعلام.
SourceName وهي SourceLink اختيارية، ولكن إذا تم توفيرها سيتم استخدامها من قبل العامل لاقتباس مصدر المعلومات عند الإجابة عن سؤال المستخدم.
static Task<IEnumerable<TextSearchProvider.TextSearchResult>> SearchAdapter(string query, CancellationToken cancellationToken)
{
// The mock search inspects the user's question and returns pre-defined snippets
// that resemble documents stored in an external knowledge source.
List<TextSearchProvider.TextSearchResult> results = new();
if (query.Contains("return", StringComparison.OrdinalIgnoreCase) || query.Contains("refund", StringComparison.OrdinalIgnoreCase))
{
results.Add(new()
{
SourceName = "Contoso Outdoors Return Policy",
SourceLink = "https://contoso.com/policies/returns",
Text = "Customers may return any item within 30 days of delivery. Items should be unused and include original packaging. Refunds are issued to the original payment method within 5 business days of inspection."
});
}
return Task.FromResult<IEnumerable<TextSearchProvider.TextSearchResult>>(results);
}
خيارات TextSearchProvider
TextSearchProvider يمكن تخصيص عبر TextSearchProviderOptions الفئة. فيما يلي مثال على إنشاء خيارات لتشغيل البحث قبل كل استدعاء نموذج والاحتفاظ بنافذة قصيرة من محفوظات الدردشة لعمليات البحث.
TextSearchProviderOptions textSearchOptions = new()
{
// Run the search prior to every model invocation and keep a short rolling window of chat history for searches.
SearchTime = TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke,
RecentMessageMemoryLimit = 6,
};
TextSearchProvider تدعم الفئة الخيارات التالية عبر TextSearchProviderOptions الفئة.
| خيار | Type | Description | Default |
|---|---|---|---|
| وقت البحث | TextSearchProviderOptions.TextSearchBehavior |
يشير إلى متى يجب تنفيذ البحث. هناك خياران، في كل مرة يتم فيها تشغيل العامل، أو عند الطلب عبر استدعاء الوظيفة. | TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke |
| FunctionToolName | string |
اسم أداة البحث المكشوفة عند العمل في وضع عند الطلب. | "بحث" |
| FunctionToolDescription | string |
وصف أداة البحث المكشوفة عند العمل في وضع عند الطلب. | "يسمح بالبحث عن معلومات إضافية للمساعدة في الإجابة على سؤال المستخدم." |
| ContextPrompt | string |
موجه السياق مسبوق بالنتائج. | "## سياق إضافي\nضع في اعتبارك المعلومات التالية من مستندات المصدر عند الاستجابة للمستخدم:" |
| CitationsPrompt | string |
التعليمات الملحقة بعد النتائج لطلب الاقتباسات. | "قم بتضمين الاقتباسات إلى المستند المصدر مع اسم المستند والارتباط إذا كان اسم المستند والارتباط متوفرين." |
| ContextFormatter | Func<IList<TextSearchProvider.TextSearchResult>, string> |
تفويض اختياري لتخصيص تنسيق قائمة النتائج بشكل كامل. إذا تم توفيرها، ContextPromptCitationsPrompt ويتم تجاهلها. |
null |
| RecentMessageMemoryLimit | int |
عدد رسائل المحادثة الأخيرة (كل من المستخدم والمساعد) التي يجب الاحتفاظ بها في الذاكرة وتضمينها عند إنشاء إدخال البحث لعمليات BeforeAIInvoke البحث. |
0 (معطل) |
| RecentMessageRolesIncluded | List<ChatRole> |
قائمة الأنواع التي ChatRole يجب تصفية الرسائل الأخيرة إليها عند تحديد الرسائل الأخيرة التي يجب تضمينها عند إنشاء إدخال البحث. |
ChatRole.User |
Tip
راجع نماذج .NET للحصول على أمثلة كاملة قابلة للتشغيل.
يوفر إطار عمل العامل عقودا أصلية لمتجر المتجهات و create_vector_search_tool(). يحول المساعد أي SupportsVectorSearch تنفيذ إلى أداة دالة، بحيث يمكن للنموذج استرداد بيانات الأساس قبل أن يجيب.
إنشاء أداة بحث متجه أصلية
أولا، حدد نموذج مخزن المتجهات الخاص بك، وأنشئ مجموعة، وقم بتحميل سجلاتها. يستخدم InMemoryCollection النموذج التالي مع OpenAIEmbeddingClient، ولكن يمكنك توفير أي مجموعة إطار عمل عامل أصلية SupportsVectorSearchتنفذ . ثم يعرض عوامل تصفية التصنيف والفئة الاختيارية للنموذج، ويقوم بتعيين كل نتيجة إلى نص أساسي، ويرشد العامل إلى البحث قبل أن يجيب:
import asyncio
import json
import os
from typing import Annotated, Any, Literal
from urllib.request import urlopen
from agent_framework import (
Agent,
Filter,
FilterGroup,
InMemoryCollection,
Param,
VectorStoreField,
create_vector_search_tool,
vectorstoremodel,
)
from agent_framework.openai import OpenAIChatClient, OpenAIEmbeddingClient
from dotenv import load_dotenv
async def main() -> None:
"""Create an in-memory hotel search tool and give it to an agent."""
api_key = os.environ["OPENAI_API_KEY"]
collection: InMemoryCollection[str, Hotel] = InMemoryCollection(
Hotel,
embedding_generator=OpenAIEmbeddingClient(
model="text-embedding-3-small",
api_key=api_key,
),
)
await collection.ensure_collection_exists()
# 1. Load the hotel records.
hotels = await asyncio.to_thread(load_hotels)
await collection.upsert(hotels)
# 2. Param values become optional model-visible filter arguments.
# When the allowed values are known, use Literal so the tool schema exposes
# them as an enum.
category = Param(
"category",
Literal["Boutique", "Budget", "Extended-Stay", "Luxury", "Resort and Spa", "Suite"],
description="Only return hotels in this category.",
)
min_rating = Param(
"min_rating",
float,
description="The minimum guest rating.",
minimum=0,
maximum=5,
)
tool = create_vector_search_tool(
collection,
description="Search the hotel dataset, optionally filtering by category and minimum rating.",
filter=FilterGroup(
"and",
(
Filter("category", "eq", category),
Filter("rating", "gte", min_rating),
),
),
result_mapper=lambda result: (
f"(hotel_id: {result['record'].hotel_id}) {result['record'].hotel_name} "
f"(rating {result['record'].rating}) - {result['record'].description}. "
f"Address: {result['record'].address.city}, {result['record'].address.country}."
),
)
# 3. The agent chooses whether to supply the exposed category and minimum-rating filters.
async with Agent(
client=OpenAIChatClient(
model="gpt-5.4-nano",
api_key=api_key,
),
name="HotelAgent",
instructions=(
"Always use the search tool to answer hotel questions. "
"Use category and minimum rating filters when the request provides them. "
"Include the hotel_id in the answer."
),
tools=[tool],
) as agent:
result = await agent.run("Find a resort and spa with a rating of at least 4.")
print(result)
تحدد العينة Hotel الكاملة النموذج وتحمل السجلات المصدر قبل إعداد المجموعة المعروضة. تعيين OPENAI_API_KEY قبل تشغيله.
تخصيص سلوك البحث
قم بالتكوين create_vector_search_tool() باستخدام الخيارات التالية:
| خيار | الغرض |
|---|---|
name |
تعيين اسم الدالة المكشوف للنموذج. استخدم اسما فريدا عند إضافة أدوات بحث متعددة. |
description |
يشرح متى ولماذا يجب أن يستخدم النموذج الأداة. |
approval_mode |
تعيين الموافقة على الأداة إلى always_require أو never_require. |
search_type |
vector التحديد أو keyword_hybrid البحث. يجب أن تدعم المجموعة الوضع المحدد. |
top وskip |
قم بتعيين قيم ترحيل ثابتة أو استخدم القيم التي تم كتابتها Param التي يوفرها النموذج. |
filter |
تطبيق محمول Filter أو FilterGroup. يمكن أن يحتوي عامل التصفية على قيم مكتوبة Param مكشوفة في مخطط الأداة. |
result_mapper |
تحويل كل SearchResponse منها إلى نص أو متعدد الوسائط Content للنموذج. |
تتضمن الأداة التي تم إنشاؤها دائما سلسلة query . تصبح أي Param قيم في عامل التصفية أو topأو skip الإعدادات وسيطات أدوات إضافية تم التحقق من صحتها.
استخدم Literal وقيودا رقمية للاحتفاظ بالقيم التي يوفرها النموذج ضمن النطاق الذي يقبله التطبيق الخاص بك.
يمكنك إنشاء أدوات متعددة للمجموعات أو أوضاع البحث المختلفة. امنح كل أداة أداة مميزة namedescription حتى يتمكن النموذج من تحديد مصدر المعرفة المناسب.
اختيار مخزن متجه أصلي
تتوفر تطبيقات Python الأصلية للبحث في الذاكرة، البحث باستخدام الذكاء الاصطناعي في Azure، وPostgreSQL مع pgvector، وQdrant، وRedis. تختلف أوضاع البحث ودورة حياة الحزمة والأوامر والقيود الخاصة بهم. راجع تكاملات مخزن المتجهات لتحديد التنفيذ وتكوينه. تحدد هذه الصفحة أيضا قواعد البيانات التي تحتوي حاليا على موصل نواة دلالية منفصل فقط.
Note
سيتوفر الدعم لهذه الميزة قريبا. راجع مستودع Agent Framework Go للحصول على أحدث حالة.
الرسم البياني RAG
بالنسبة إلى GraphRAG باستخدام البحث المثري باجتياز الرسم البياني باستخدام استعلامات Cypher، راجع موفر Neo4j GraphRAG.