Útmutató: OpenAIAssistantAgent fájlkeresés

Fontos

Ez a funkció a kiadásra jelölt fázisban van. A funkciók ebben a szakaszban szinte teljesek és általában stabilak, bár kisebb finomításokon vagy optimalizálásokon eshetnek át, mielőtt elérnék a teljes általános rendelkezésre állást.

Áttekintés

Ebben a mintában bemutatjuk, hogyan végezheti el a szövegértési feladatokat egy fájlkereső eszközzel OpenAIAssistantAgent . A megközelítés lépésről lépésre történik, így a folyamat során egyértelmű és pontos lesz a folyamat. A feladat részeként az ügynök dokumentum-idézeteket ad meg a válaszban.

A streamelés az ügynök válaszainak továbbítására szolgál. Ez valós idejű frissítéseket biztosít a tevékenység előrehaladása során.

Első lépések

A funkciókódolás előtt győződjön meg arról, hogy a fejlesztési környezet teljesen be van állítva és konfigurálva van.

Ha csomagfüggőségeket szeretne hozzáadni a parancssorból, használja a dotnet következő parancsot:

dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.Binder
dotnet add package Microsoft.Extensions.Configuration.UserSecrets
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
dotnet add package Microsoft.SemanticKernel
dotnet add package Microsoft.SemanticKernel.Agents.OpenAI --prerelease

Fontos

Ha NuGet-csomagokat kezel a Visual Studióban, ellenőrizze, hogy Include prerelease van-e bejelölve.

A projektfájlnak (.csproj) a következő PackageReference definíciókat kell tartalmaznia:

  <ItemGroup>
    <PackageReference Include="Azure.Identity" Version="<stable>" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="<stable>" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="<stable>" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="<stable>" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="<stable>" />
    <PackageReference Include="Microsoft.SemanticKernel" Version="<latest>" />
    <PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" Version="<latest>" />
  </ItemGroup>

A Agent Framework kísérleti jellegű, és figyelmeztetések elnyomását igényli. Ez a projektfájlban mint tulajdonság szerepelhet (.csproj):

  <PropertyGroup>
    <NoWarn>$(NoWarn);CA2007;IDE1006;SKEXP0001;SKEXP0110;OPENAI001</NoWarn>
  </PropertyGroup>

Emellett másolja a Grimms-The-King-of-the-Golden-Mountain.txt, Grimms-The-Water-of-Life.txt és Grimms-The-White-Snake.txt nyilvános tartalmat a Semantic Kernel LearnResources Project-ból. Vegye fel ezeket a fájlokat a projektmappába, és konfigurálja, hogy azokat a kimeneti könyvtárba másolja:

  <ItemGroup>
    <None Include="Grimms-The-King-of-the-Golden-Mountain.txt">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Include="Grimms-The-Water-of-Life.txt">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Include="Grimms-The-White-Snake.txt">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

Először hozzon létre egy mappát, amely a szkriptet (.py fájlt) és a mintaerőforrásokat fogja tárolni. Tartalmazza a következő importálásokat a .py fájl tetején:

import asyncio
import os

from semantic_kernel.agents import AssistantAgentThread, AzureAssistantAgent
from semantic_kernel.contents import StreamingAnnotationContent

Emellett másolja a Grimms-The-King-of-the-Golden-Mountain.txt, Grimms-The-Water-of-Life.txt és Grimms-The-White-Snake.txt nyilvános tartalmat a Semantic Kernel LearnResources Project-ból. Vegye fel ezeket a fájlokat a projektmappába.

A funkció jelenleg nem érhető el a Javában.

Konfiguráció

Ez a minta konfigurációs beállítást igényel a távoli szolgáltatásokhoz való csatlakozáshoz. Meg kell adnia az OpenAI vagy az Azure OpenAI beállításait.

# OpenAI
dotnet user-secrets set "OpenAISettings:ApiKey" "<api-key>"
dotnet user-secrets set "OpenAISettings:ChatModel" "gpt-4o"

# Azure OpenAI
dotnet user-secrets set "AzureOpenAISettings:ApiKey" "<api-key>" # Not required if using token-credential
dotnet user-secrets set "AzureOpenAISettings:Endpoint" "https://lightspeed-team-shared-openai-eastus.openai.azure.com/"
dotnet user-secrets set "AzureOpenAISettings:ChatModelDeployment" "gpt-4o"

A rendszer az alábbi osztályt használja az összes ügynök-példában. A megfelelő működés érdekében mindenképpen vegye fel a projektbe. Ez az osztály alapvető összetevőként szolgál az alábbi példákhoz.

using System.Reflection;
using Microsoft.Extensions.Configuration;

namespace AgentsSample;

public class Settings
{
    private readonly IConfigurationRoot configRoot;

    private AzureOpenAISettings azureOpenAI;
    private OpenAISettings openAI;

    public AzureOpenAISettings AzureOpenAI => this.azureOpenAI ??= this.GetSettings<Settings.AzureOpenAISettings>();
    public OpenAISettings OpenAI => this.openAI ??= this.GetSettings<Settings.OpenAISettings>();

    public class OpenAISettings
    {
        public string ChatModel { get; set; } = string.Empty;
        public string ApiKey { get; set; } = string.Empty;
    }

    public class AzureOpenAISettings
    {
        public string ChatModelDeployment { get; set; } = string.Empty;
        public string Endpoint { get; set; } = string.Empty;
        public string ApiKey { get; set; } = string.Empty;
    }

    public TSettings GetSettings<TSettings>() =>
        this.configRoot.GetRequiredSection(typeof(TSettings).Name).Get<TSettings>()!;

    public Settings()
    {
        this.configRoot =
            new ConfigurationBuilder()
                .AddEnvironmentVariables()
                .AddUserSecrets(Assembly.GetExecutingAssembly(), optional: true)
                .Build();
    }
}

A mintakód futtatásához szükséges megfelelő konfiguráció használatának leggyorsabb módja egy .env fájl létrehozása a projekt gyökerénél (ahol a szkript fut).

Konfigurálja a következő beállításokat az .env fájlban az Azure OpenAI vagy az OpenAI használatához.

AZURE_OPENAI_API_KEY="..."
AZURE_OPENAI_ENDPOINT="https://<resource-name>.openai.azure.com/"
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME="..."
AZURE_OPENAI_API_VERSION="..."

OPENAI_API_KEY="sk-..."
OPENAI_ORG_ID=""
OPENAI_CHAT_MODEL=""

Borravaló

Az Azure Assistants legalább 2024-05-01 előzetes verziójú API-verziót igényel. Az új funkciók bevezetésekor az API-verziók ennek megfelelően frissülnek. A jelen írás idején a legújabb verzió a 2025-01-01-preview. A legfrissebb verzió részleteiért lásd az Azure OpenAI API előzetes verzió életciklusai.

A konfigurálás után a megfelelő AI-szolgáltatásosztályok felveszik a szükséges változókat, és a példányosítás során használják őket.

A funkció jelenleg nem érhető el a Javában.

Kódolás

A minta kódolási folyamata a következőket foglalja magában:

  1. Beállítás – Beállítások inicializálása és a beépülő modul.
  2. Ügynökdefiníció - Hozzon létre _Chat_CompletionAgent, sablon alapú utasítások és beépülő modul használatával.
  3. A csevegési hurok – Írja meg a felhasználói/ügynöki interakciót hajtó hurkot.

A teljes példakód az Utolsó szakaszban található. A teljes megvalósításhoz tekintse meg ezt a szakaszt.

Beállítás

A OpenAIAssistantAgentlétrehozása előtt győződjön meg arról, hogy a konfigurációs beállítások elérhetők, és előkészíti a fájlerőforrásokat.

Példányosítsa az Settings osztályt, amelyre az előző Konfiguráció szakaszban hivatkoztunk. A beállítások segítségével létrehozhat egy AzureOpenAIClient, amelyet az Ügynökdefinícióhoz, valamint fájlok feltöltéséhez és egy VectorStore létrehozásához lehet használni.

Settings settings = new();

AzureOpenAIClient client = OpenAIAssistantAgent.CreateAzureOpenAIClient(new AzureCliCredential(), new Uri(settings.AzureOpenAI.Endpoint));

Az Asszisztensügynök statikus metódusa create_client() kezeli az ügyfél létrehozását és visszaadását a kívánt konfiguráció alapján. A pydantic-beállítások a környezeti változók betöltésére szolgálnak először a környezeti változókból vagy a .env fájlból. Átmehet a api_key, api_version, deployment_name vagy endpointváltozók között, amelyek elsőbbséget élveznek a konfigurált környezeti változókkal szemben.

# Create the client using Azure OpenAI resources and configuration
client = AzureAssistantAgent.create_client()

A funkció jelenleg nem érhető el a Javában.

Most hozzon létre egy üres _Vector Tárolót a Fájlkeresés eszközzel való használatra:

A AzureOpenAIClient segítségével hozzáférhet egy VectorStoreClient-hoz és létrehozhat egy VectorStore-t.

Console.WriteLine("Creating store...");
VectorStoreClient storeClient = client.GetVectorStoreClient();
CreateVectorStoreOperation operation = await storeClient.CreateVectorStoreAsync(waitUntilCompleted: true);
string storeId = operation.VectorStoreId;
# Upload the files to the client
file_ids: list[str] = []
for path in [get_filepath_for_filename(filename) for filename in filenames]:
    with open(path, "rb") as file:
        file = await client.files.create(file=file, purpose="assistants")
        file_ids.append(file.id)

vector_store = await client.vector_stores.create(
    name="assistant_search",
    file_ids=file_ids,
)

# Get the file search tool and resources
file_search_tools, file_search_tool_resources = AzureAssistantAgent.configure_file_search_tool(
    vector_store_ids=vector_store.id
)

A funkció jelenleg nem érhető el a Javában.

Deklaráljuk az előző konfigurációs szakaszban leírt három tartalomfájlt:

private static readonly string[] _fileNames =
    [
        "Grimms-The-King-of-the-Golden-Mountain.txt",
        "Grimms-The-Water-of-Life.txt",
        "Grimms-The-White-Snake.txt",
    ];
filenames = [
    "Grimms-The-King-of-the-Golden-Mountain.txt",
    "Grimms-The-Water-of-Life.txt",
    "Grimms-The-White-Snake.txt",
]

A funkció jelenleg nem érhető el a Javában.

Most töltse fel ezeket a fájlokat, és adja hozzá őket a Vector Store-hoz a korábban létrehozott VectorStoreClient ügyfelek használatával, hogy feltöltse az egyes fájlokat egy-egy OpenAIFileClient fájllal, és hozzáadja őket a Vector Store-hoz, megőrizve az eredményként kapott fájlhivatkozásokat.

Dictionary<string, OpenAIFile> fileReferences = [];

Console.WriteLine("Uploading files...");
OpenAIFileClient fileClient = client.GetOpenAIFileClient();
foreach (string fileName in _fileNames)
{
    OpenAIFile fileInfo = await fileClient.UploadFileAsync(fileName, FileUploadPurpose.Assistants);
    await storeClient.AddFileToVectorStoreAsync(storeId, fileInfo.Id, waitUntilCompleted: true);
    fileReferences.Add(fileInfo.Id, fileInfo);
}

A funkció jelenleg nem érhető el a Javában.

Ügynökdefiníció

Most készen állunk egy OpenAIAssistantAgent példányának létrehozására. Az ügynök konfigurálva van a célmodell , az Utasítások és a Fájlkeresés eszköz engedélyezésével. Emellett explicit módon társítjuk a Vektortárat a Fájlkereső eszközzel.

A AzureOpenAIClient-t ismét felhasználjuk a OpenAIAssistantAgent létrehozásakor.

Console.WriteLine("Defining assistant...");
Assistant assistant =
    await assistantClient.CreateAssistantAsync(
        settings.AzureOpenAI.ChatModelDeployment,
        name: "SampleAssistantAgent",
        instructions:
                """
                The document store contains the text of fictional stories.
                Always analyze the document store to provide an answer to the user's question.
                Never rely on your knowledge of stories not included in the document store.
                Always format response using markdown.
                """,
        enableFileSearch: true,
        vectorStoreId: storeId);

// Create agent
OpenAIAssistantAgent agent = new(assistant, assistantClient);
# Create the assistant definition
definition = await client.beta.assistants.create(
    model=AzureOpenAISettings().chat_deployment_name,
    instructions="""
        The document store contains the text of fictional stories.
        Always analyze the document store to provide an answer to the user's question.
        Never rely on your knowledge of stories not included in the document store.
        Always format response using markdown.
        """,
    name="SampleAssistantAgent",
    tools=file_search_tools,
    tool_resources=file_search_tool_resources,
)

# Create the agent using the client and the assistant definition
agent = AzureAssistantAgent(
    client=client,
    definition=definition,
)

A funkció jelenleg nem érhető el a Javában.

A Chat ciklus

Végre össze tudjuk hangolni a felhasználó és a Agentközötti interakciót. Először hozzon létre egy AgentThread a beszélgetés állapotának fenntartásához és egy üres hurok létrehozásához.

Gondoskodjunk arról is, hogy az erőforrások a végrehajtás végén el legyenek távolítva a szükségtelen díjak minimalizálása érdekében.

Console.WriteLine("Creating thread...");
OpenAIAssistantAgent agentThread = new();

Console.WriteLine("Ready!");

try
{
    bool isComplete = false;
    do
    {
        // Processing occurs here
    } while (!isComplete);
}
finally
{
    Console.WriteLine();
    Console.WriteLine("Cleaning-up...");
    await Task.WhenAll(
        [
            agentThread.DeleteAsync();
            assistantClient.DeleteAssistantAsync(assistant.Id),
            storeClient.DeleteVectorStoreAsync(storeId),
            ..fileReferences.Select(fileReference => fileClient.DeleteFileAsync(fileReference.Key))
        ]);
}
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: AssistantAgentThread = None

try:
    is_complete: bool = False
    while not is_complete:
        # Processing occurs here

finally:
    print("\nCleaning up resources...")
    [await client.files.delete(file_id) for file_id in file_ids]
    await client.vector_stores.delete(vector_store.id)
    await thread.delete() if thread else None
    await client.beta.assistants.delete(agent.id)

A funkció jelenleg nem érhető el a Javában.

Most rögzítsük a felhasználói bemenetet az előző ciklusban. Ebben az esetben a rendszer figyelmen kívül hagyja az üres bemenetet, és a kifejezés EXIT azt jelzi, hogy a beszélgetés befejeződött.

Console.WriteLine();
Console.Write("> ");
string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
    continue;
}
if (input.Trim().Equals("EXIT", StringComparison.OrdinalIgnoreCase))
{
    isComplete = true;
    break;
}

var message = new ChatMessageContent(AuthorRole.User, input);
Console.WriteLine();
user_input = input("User:> ")
if not user_input:
    continue

if user_input.lower() == "exit":
    is_complete = True
    break

A funkció jelenleg nem érhető el a Javában.

A Agent válasz meghívása előtt adjunk hozzá egy segédmetódust, amellyel anSI-szögletes zárójelekké formázzuk a Unicode-széljegyzeteket.

private static string ReplaceUnicodeBrackets(this string content) =>
    content?.Replace('【', '[').Replace('】', ']');
# No special handling required.

A funkció jelenleg nem érhető el a Javában.

Ha Agent választ szeretne létrehozni a felhasználói bemenetre, hívja meg az ügynököt az üzenet és az ügynökszál megadásával. Ebben a példában egy streamelt választ választunk, és rögzítjük a kapcsolódó idézetjegyzeteket a válaszciklus végén való megjelenítéshez. Figyelje meg, hogy minden streamelt adattömb újraformázása az előző segédmetódus használatával történik.

List<StreamingAnnotationContent> footnotes = [];
await foreach (StreamingChatMessageContent chunk in agent.InvokeStreamingAsync(message, agentThread))
{
    // Capture annotations for footnotes
    footnotes.AddRange(chunk.Items.OfType<StreamingAnnotationContent>());

    // Render chunk with replacements for unicode brackets.
    Console.Write(chunk.Content.ReplaceUnicodeBrackets());
}

Console.WriteLine();

// Render footnotes for captured annotations.
if (footnotes.Count > 0)
{
    Console.WriteLine();
    foreach (StreamingAnnotationContent footnote in footnotes)
    {
        Console.WriteLine($"#{footnote.Quote.ReplaceUnicodeBrackets()} - {fileReferences[footnote.FileId!].Filename} (Index: {footnote.StartIndex} - {footnote.EndIndex})");
    }
}
footnotes: list[StreamingAnnotationContent] = []
async for response in agent.invoke_stream(messages=user_input, thread=thread):
    thread = response.thread
    footnotes.extend([item for item in response.items if isinstance(item, StreamingAnnotationContent)])

    print(f"{response.content}", end="", flush=True)

print()

if len(footnotes) > 0:
    for footnote in footnotes:
        print(
            f"\n`{footnote.quote}` => {footnote.file_id} "
            f"(Index: {footnote.start_index} - {footnote.end_index})"
        )

A funkció jelenleg nem érhető el a Javában.

Végső

Az összes lépés összefoglalásával megkapjuk a példához tartozó végleges kódot. A teljes megvalósítást alább találja.

Próbálja meg használni a következő javasolt bemeneteket:

  1. Mi a bekezdések száma az egyes történetekhez?
  2. Hozzon létre egy táblát, amely azonosítja az egyes történetek főhősét és antagonistát.
  3. Mi az erkölcs a Fehér Kígyóban?
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.ChatCompletion;
using OpenAI.Assistants;
using OpenAI.Files;
using OpenAI.VectorStores;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AgentsSample;

public static class Program
{
    private static readonly string[] _fileNames =
        [
            "Grimms-The-King-of-the-Golden-Mountain.txt",
            "Grimms-The-Water-of-Life.txt",
            "Grimms-The-White-Snake.txt",
        ];

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
    public static async Task Main()
    {
        // Load configuration from environment variables or user secrets.
        Settings settings = new();

        // Initialize the clients
        AzureOpenAIClient client = OpenAIAssistantAgent.CreateAzureOpenAIClient(new AzureCliCredential(), new Uri(settings.AzureOpenAI.Endpoint));
        //OpenAIClient client = OpenAIAssistantAgent.CreateOpenAIClient(new ApiKeyCredential(settings.OpenAI.ApiKey)));
        AssistantClient assistantClient = client.GetAssistantClient();
        OpenAIFileClient fileClient = client.GetOpenAIFileClient();
        VectorStoreClient storeClient = client.GetVectorStoreClient();

        // Create the vector store
        Console.WriteLine("Creating store...");
        CreateVectorStoreOperation operation = await storeClient.CreateVectorStoreAsync(waitUntilCompleted: true);
        string storeId = operation.VectorStoreId;

        // Upload files and retain file references.
        Console.WriteLine("Uploading files...");
        Dictionary<string, OpenAIFile> fileReferences = [];
        foreach (string fileName in _fileNames)
        {
            OpenAIFile fileInfo = await fileClient.UploadFileAsync(fileName, FileUploadPurpose.Assistants);
            await storeClient.AddFileToVectorStoreAsync(storeId, fileInfo.Id, waitUntilCompleted: true);
            fileReferences.Add(fileInfo.Id, fileInfo);
        }

        // Define assistant
        Console.WriteLine("Defining assistant...");
        Assistant assistant =
            await assistantClient.CreateAssistantAsync(
                settings.AzureOpenAI.ChatModelDeployment,
                name: "SampleAssistantAgent",
                instructions:
                        """
                        The document store contains the text of fictional stories.
                        Always analyze the document store to provide an answer to the user's question.
                        Never rely on your knowledge of stories not included in the document store.
                        Always format response using markdown.
                        """,
                enableFileSearch: true,
                vectorStoreId: storeId);

        // Create agent
        OpenAIAssistantAgent agent = new(assistant, assistantClient);

        // Create the conversation thread
        Console.WriteLine("Creating thread...");
        AssistantAgentThread agentThread = new();

        Console.WriteLine("Ready!");

        try
        {
            bool isComplete = false;
            do
            {
                Console.WriteLine();
                Console.Write("> ");
                string input = Console.ReadLine();
                if (string.IsNullOrWhiteSpace(input))
                {
                    continue;
                }
                if (input.Trim().Equals("EXIT", StringComparison.OrdinalIgnoreCase))
                {
                    isComplete = true;
                    break;
                }

                var message = new ChatMessageContent(AuthorRole.User, input);
                Console.WriteLine();

                List<StreamingAnnotationContent> footnotes = [];
                await foreach (StreamingChatMessageContent chunk in agent.InvokeStreamingAsync(message, agentThread))
                {
                    // Capture annotations for footnotes
                    footnotes.AddRange(chunk.Items.OfType<StreamingAnnotationContent>());

                    // Render chunk with replacements for unicode brackets.
                    Console.Write(chunk.Content.ReplaceUnicodeBrackets());
                }

                Console.WriteLine();

                // Render footnotes for captured annotations.
                if (footnotes.Count > 0)
                {
                    Console.WriteLine();
                    foreach (StreamingAnnotationContent footnote in footnotes)
                    {
                        Console.WriteLine($"#{footnote.Quote.ReplaceUnicodeBrackets()} - {fileReferences[footnote.FileId!].Filename} (Index: {footnote.StartIndex} - {footnote.EndIndex})");
                    }
                }
            } while (!isComplete);
        }
        finally
        {
            Console.WriteLine();
            Console.WriteLine("Cleaning-up...");
            await Task.WhenAll(
                [
                    agentThread.DeleteAsync(),
                    assistantClient.DeleteAssistantAsync(assistant.Id),
                    storeClient.DeleteVectorStoreAsync(storeId),
                    ..fileReferences.Select(fileReference => fileClient.DeleteFileAsync(fileReference.Key))
                ]);
        }
    }

    private static string ReplaceUnicodeBrackets(this string content) =>
        content?.Replace('【', '[').Replace('】', ']');
}
# Copyright (c) Microsoft. All rights reserved.

import asyncio
import os

from semantic_kernel.agents import AssistantAgentThread, AzureAssistantAgent
from semantic_kernel.connectors.ai.open_ai import AzureOpenAISettings
from semantic_kernel.contents import StreamingAnnotationContent

"""
The following sample demonstrates how to create a simple,
OpenAI assistant agent that utilizes the vector store
to answer questions based on the uploaded documents.

This is the full code sample for the Semantic Kernel Learn Site: How-To: Open AI Assistant Agent File Search

https://learn.microsoft.com/semantic-kernel/frameworks/agent/examples/example-assistant-search?pivots=programming-language-python
"""


def get_filepath_for_filename(filename: str) -> str:
    base_directory = os.path.join(
        os.path.dirname(os.path.dirname(os.path.realpath(__file__))),
        "resources",
    )
    return os.path.join(base_directory, filename)


filenames = [
    "Grimms-The-King-of-the-Golden-Mountain.txt",
    "Grimms-The-Water-of-Life.txt",
    "Grimms-The-White-Snake.txt",
]


async def main():
    # Create the client using Azure OpenAI resources and configuration
    client = AzureAssistantAgent.create_client()

    # Upload the files to the client
    file_ids: list[str] = []
    for path in [get_filepath_for_filename(filename) for filename in filenames]:
        with open(path, "rb") as file:
            file = await client.files.create(file=file, purpose="assistants")
            file_ids.append(file.id)

    vector_store = await client.vector_stores.create(
        name="assistant_search",
        file_ids=file_ids,
    )

    # Get the file search tool and resources
    file_search_tools, file_search_tool_resources = AzureAssistantAgent.configure_file_search_tool(
        vector_store_ids=vector_store.id
    )

    # Create the assistant definition
    definition = await client.beta.assistants.create(
        model=AzureOpenAISettings().chat_deployment_name,
        instructions="""
            The document store contains the text of fictional stories.
            Always analyze the document store to provide an answer to the user's question.
            Never rely on your knowledge of stories not included in the document store.
            Always format response using markdown.
            """,
        name="SampleAssistantAgent",
        tools=file_search_tools,
        tool_resources=file_search_tool_resources,
    )

    # Create the agent using the client and the assistant definition
    agent = AzureAssistantAgent(
        client=client,
        definition=definition,
    )

    thread: AssistantAgentThread | None = None

    try:
        is_complete: bool = False
        while not is_complete:
            user_input = input("User:> ")
            if not user_input:
                continue

            if user_input.lower() == "exit":
                is_complete = True
                break

            footnotes: list[StreamingAnnotationContent] = []
            async for response in agent.invoke_stream(messages=user_input, thread=thread):
                footnotes.extend([item for item in response.items if isinstance(item, StreamingAnnotationContent)])

                print(f"{response.content}", end="", flush=True)
                thread = response.thread

            print()

            if len(footnotes) > 0:
                for footnote in footnotes:
                    print(
                        f"\n`{footnote.quote}` => {footnote.file_id} "
                        f"(Index: {footnote.start_index} - {footnote.end_index})"
                    )

    finally:
        print("\nCleaning up resources...")
        [await client.files.delete(file_id) for file_id in file_ids]
        await client.vector_stores.delete(vector_store.id)
        await thread.delete() if thread else None
        await client.beta.assistants.delete(agent.id)


if __name__ == "__main__":
    asyncio.run(main())

A teljes kóda fent látható módon az adattárunkban található.

A funkció jelenleg nem érhető el a Javában.

Következő lépések