RAG

يدعم Microsoft Agent Framework إضافة قدرات Retrieval Augmented Generation (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 للحصول على أمثلة كاملة قابلة للتشغيل.

يدعم إطار عمل العامل استخدام مجموعات VectorStore الخاصة نواة دلالية لتوفير قدرات RAG للوكلاء. يتم تحقيق ذلك من خلال وظيفة الجسر التي تحول وظائف البحث نواة دلالية إلى أدوات إطار عمل العامل.

إنشاء أداة بحث من VectorStore

يرجع create_search_functionKernelFunction الأسلوب من مجموعة نواة دلالية VectorStore التي يمكن تحويلها إلى أداة إطار عمل العامل باستخدام .as_agent_framework_tool(). استخدم وثائق موصلات مخزن المتجهات لمعرفة كيفية إعداد مجموعات مخزن متجهات مختلفة.

from semantic_kernel.connectors.ai.open_ai import OpenAITextEmbedding
from semantic_kernel.connectors.azure_ai_search import AzureAISearchCollection
from semantic_kernel.functions import KernelParameterMetadata
from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient

# Define your data model
class SupportArticle:
    article_id: str
    title: str
    content: str
    category: str
    # ... other fields

# Create an Azure AI Search collection
collection = AzureAISearchCollection[str, SupportArticle](
    record_type=SupportArticle,
    embedding_generator=OpenAITextEmbedding()
)

async with collection:
    await collection.ensure_collection_exists()
    # Load your knowledge base articles into the collection
    # await collection.upsert(articles)

    # Create a search function from the collection
    search_function = collection.create_search_function(
        function_name="search_knowledge_base",
        description="Search the knowledge base for support articles and product information.",
        search_type="keyword_hybrid",
        parameters=[
            KernelParameterMetadata(
                name="query",
                description="The search query to find relevant information.",
                type="str",
                is_required=True,
                type_object=str,
            ),
            KernelParameterMetadata(
                name="top",
                description="Number of results to return.",
                type="int",
                default_value=3,
                type_object=int,
            ),
        ],
        string_mapper=lambda x: f"[{x.record.category}] {x.record.title}: {x.record.content}",
    )

    # Convert the search function to an Agent Framework tool
    search_tool = search_function.as_agent_framework_tool()

    # Create an agent with the search tool
    agent = Agent(
        client=OpenAIChatClient(model="gpt-4o"),
        instructions="You are a helpful support specialist. Use the search tool to find relevant information before answering questions. Always cite your sources.",
        tools=search_tool
    )

    # Use the agent with RAG capabilities
    response = await agent.run("How do I return a product?")
    print(response.text)

Important

تتطلب هذه الميزة semantic-kernel الإصدار 1.38 أو أعلى.

تخصيص سلوك البحث

يمكنك تخصيص دالة البحث بخيارات مختلفة:

# Create a search function with filtering and custom formatting
search_function = collection.create_search_function(
    function_name="search_support_articles",
    description="Search for support articles in specific categories.",
    search_type="keyword_hybrid",
    # Apply filters to restrict search scope
    filter=lambda x: x.is_published == True,
    parameters=[
        KernelParameterMetadata(
            name="query",
            description="What to search for in the knowledge base.",
            type="str",
            is_required=True,
            type_object=str,
        ),
        KernelParameterMetadata(
            name="category",
            description="Filter by category: returns, shipping, products, or billing.",
            type="str",
            type_object=str,
        ),
        KernelParameterMetadata(
            name="top",
            description="Maximum number of results to return.",
            type="int",
            default_value=5,
            type_object=int,
        ),
    ],
    # Customize how results are formatted for the agent
    string_mapper=lambda x: f"Article: {x.record.title}\nCategory: {x.record.category}\nContent: {x.record.content}\nSource: {x.record.article_id}",
)

للحصول على التفاصيل الكاملة حول المعلمات المتوفرة ل create_search_function، راجع وثائق نواة دلالية.

استخدام دالات بحث متعددة

يمكنك توفير أدوات بحث متعددة لعامل لمجالات معرفية مختلفة:

# Create search functions for different knowledge bases
product_search = product_collection.create_search_function(
    function_name="search_products",
    description="Search for product information and specifications.",
    search_type="semantic_hybrid",
    string_mapper=lambda x: f"{x.record.name}: {x.record.description}",
).as_agent_framework_tool()

policy_search = policy_collection.create_search_function(
    function_name="search_policies",
    description="Search for company policies and procedures.",
    search_type="keyword_hybrid",
    string_mapper=lambda x: f"Policy: {x.record.title}\n{x.record.content}",
).as_agent_framework_tool()

# Create an agent with multiple search tools
agent = Agent(
    client=chat_client,
    instructions="You are a support agent. Use the appropriate search tool to find information before answering. Cite your sources.",
    tools=[product_search, policy_search]
)

يمكنك أيضا إنشاء دالات بحث متعددة من نفس المجموعة مع أوصاف ومعلمات مختلفة لتوفير قدرات بحث متخصصة:

# Create multiple search functions from the same collection
# Generic search for broad queries
general_search = support_collection.create_search_function(
    function_name="search_all_articles",
    description="Search all support articles for general information.",
    search_type="semantic_hybrid",
    parameters=[
        KernelParameterMetadata(
            name="query",
            description="The search query.",
            type="str",
            is_required=True,
            type_object=str,
        ),
    ],
    string_mapper=lambda x: f"{x.record.title}: {x.record.content}",
).as_agent_framework_tool()

# Detailed lookup for specific article IDs
detail_lookup = support_collection.create_search_function(
    function_name="get_article_details",
    description="Get detailed information for a specific article by its ID.",
    search_type="keyword",
    top=1,
    parameters=[
        KernelParameterMetadata(
            name="article_id",
            description="The specific article ID to retrieve.",
            type="str",
            is_required=True,
            type_object=str,
        ),
    ],
    string_mapper=lambda x: f"Title: {x.record.title}\nFull Content: {x.record.content}\nLast Updated: {x.record.updated_date}",
).as_agent_framework_tool()

# Create an agent with both search functions
agent = Agent(
    client=chat_client,
    instructions="You are a support agent. Use search_all_articles for general queries and get_article_details when you need full details about a specific article.",
    tools=[general_search, detail_lookup]
)

يسمح هذا الأسلوب للعامل باختيار استراتيجية البحث الأكثر ملاءمة استنادا إلى استعلام المستخدم.

موصلات VectorStore المدعومة

يعمل هذا النمط مع أي موصل نواة دلالية VectorStore، بما في ذلك:

  • البحث باستخدام الذكاء الاصطناعي في Azure (AzureAISearchCollection)
  • Qdrant (QdrantCollection)
  • Pinecone (PineconeCollection)
  • Redis (RedisCollection)
  • Weaviate (WeaviateCollection)
  • In-Memory (InMemoryVectorStoreCollection)
  • والمزيد

يوفر كل موصل نفس create_search_function الأسلوب الذي يمكن توصيله بأدوات إطار عمل العامل، ما يسمح لك باختيار قاعدة بيانات المتجهات التي تناسب احتياجاتك بشكل أفضل. راجع القائمة الكاملة هنا.

Note

سيتوفر الدعم لهذه الميزة قريبا. راجع مستودع Agent Framework Go للحصول على أحدث حالة.

الرسم البياني RAG

بالنسبة إلى GraphRAG باستخدام البحث المثري باجتياز الرسم البياني باستخدام استعلامات Cypher، راجع موفر Neo4j GraphRAG.

الخطوات التالية