Udostępnij przez


Instrukcje: wyszukiwanie plików OpenAIAssistantAgent

Ważny

Ta funkcja jest na etapie wersji kandydującej do wydania. Funkcje na tym etapie są prawie kompletne i ogólnie stabilne, choć mogą przejść drobne udoskonalenia lub optymalizacje przed osiągnięciem pełnej ogólnej dostępności.

Omówienie

W tym przykładzie zbadamy, jak używać narzędzia elementu OpenAIAssistantAgent do wyszukiwania plików i realizacji zadań związanych ze zrozumieniem. Podejście będzie krok po kroku, zapewniając przejrzystość i precyzję w całym procesie. W ramach zadania agent udostępni cytaty dokumentów w odpowiedzi.

Odpowiedzi agenta będą dostarczane przez przesyłanie strumieniowe. Zapewni to aktualizacje w czasie rzeczywistym w miarę postępu zadania.

Wprowadzenie

Przed kontynuowaniem tworzenia funkcji upewnij się, że środowisko programistyczne jest w pełni gotowe do użycia i skonfigurowane.

Aby dodać zależności pakietów z wiersza polecenia, użyj dotnet polecenia :

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

Ważny

Jeśli zarządzasz pakietami NuGet w programie Visual Studio, upewnij się, że Include prerelease jest zaznaczone.

Plik projektu (.csproj) powinien zawierać następujące PackageReference definicje:

  <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>

Agent Framework jest eksperymentalna i wymaga wyłączania ostrzeżeń. Może to zostać rozwiązane jako właściwość w pliku projektu (.csproj):

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

Ponadto skopiuj zawartość z domeny publicznej Grimms-The-King-of-the-Golden-Mountain.txt, Grimms-The-Water-of-Life.txt i Grimms-The-White-Snake.txt z Projektu Semantycznego JądraLearnResources. Dodaj te pliki w folderze projektu i skonfiguruj ich skopiowanie do katalogu wyjściowego:

  <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>

Zacznij od utworzenia folderu, który będzie przechowywać skrypt (.py plik) i przykładowe zasoby. Uwzględnij następujące importy na początku pliku .py.

import asyncio
import os

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

Ponadto skopiuj zawartość z domeny publicznej Grimms-The-King-of-the-Golden-Mountain.txt, Grimms-The-Water-of-Life.txt i Grimms-The-White-Snake.txt z Projektu Semantycznego JądraLearnResources. Dodaj te pliki w folderze projektu.

Funkcja jest obecnie niedostępna w języku Java.

Konfigurowanie

Ten przykład wymaga ustawienia konfiguracji w celu nawiązania połączenia z usługami zdalnymi. Musisz zdefiniować ustawienia dla OpenAI lub Azure OpenAI.

# 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"

Poniższa klasa jest używana we wszystkich przykładach Agentów. Pamiętaj, aby uwzględnić go w projekcie, aby zapewnić odpowiednią funkcjonalność. Ta klasa służy jako podstawowy składnik dla poniższych przykładów.

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();
    }
}

Najszybszym sposobem rozpoczęcia pracy z właściwą konfiguracją uruchamiania przykładowego kodu jest utworzenie .env pliku w katalogu głównym projektu (w którym jest uruchamiany skrypt).

Skonfiguruj następujące ustawienia w pliku .env dla Azure OpenAI lub OpenAI.

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_ID=""

Napiwek

Asystenci Azure wymagają wersji API co najmniej 2024-05-01-preview. W miarę wprowadzania nowych funkcji wersje interfejsu API są odpowiednio aktualizowane. Zgodnie z tym zapisem najnowsza wersja to 2025-01-01-preview. Aby uzyskać najbardziej aktualne informacje o wersji, zapoznaj się z cyklem życia wersji zapoznawczej interfejsu API Azure OpenAI.

Po skonfigurowaniu odpowiednie klasy usług AI będą pobierać wymagane zmienne i wykorzystywać je podczas inicjalizacji.

Funkcja jest obecnie niedostępna w języku Java.

Kodowanie

Proces kodowania dla tego przykładu obejmuje:

  1. Konfiguracja — inicjowanie ustawień i wtyczki.
  2. Definicja agenta — utwórz _Chat_CompletionAgent za pomocą sformatowanych instrukcji i wtyczki.
  3. Pętla czatu — zapis pętli, która napędza interakcję użytkownika/agenta.

Pełny przykładowy kod znajduje się w sekcji Final. Zapoznaj się z sekcją dotyczącą pełnej implementacji.

Ustawienia

Przed utworzeniem OpenAIAssistantAgentupewnij się, że ustawienia konfiguracji są dostępne i przygotuj zasoby plików.

Utwórz wystąpienie klasy Settings, do której odwołuje się poprzednia sekcja Konfiguracja. Użyj ustawień, aby również utworzyć AzureOpenAIClient, który będzie używany do Definicji Agenta, a także do przesyłania plików i tworzenia VectorStore.

Settings settings = new();

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

Metoda create_client() statyczna w agencie Asystenta obsługuje tworzenie klienta i zwracanie go na podstawie żądanej konfiguracji. Ustawienia Pydantic są używane do ładowania zmiennych środowiskowych najpierw z samych zmiennych środowiskowych, a następnie z pliku .env. Można przekazać api_key, api_version, deployment_name lub endpoint, które będą miały pierwszeństwo przed wszystkimi skonfigurowanymi zmiennymi środowiskowymi.

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

Funkcja jest obecnie niedostępna w języku Java.

Teraz utwórz pusty magazyn _Vector do użycia z narzędziem wyszukiwania plików:

Użyj elementu , AzureOpenAIClient aby uzyskać dostęp do elementu VectorStoreClient i utworzyć element VectorStore.

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
)

Funkcja jest obecnie niedostępna w języku Java.

Zadeklarujmy trzy pliki zawartości opisane w poprzedniej sekcji Konfiguracja :

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",
]

Funkcja jest obecnie niedostępna w języku Java.

Teraz przekaż te pliki i dodaj je do Magazynu Wektorów, używając wcześniej utworzonych klientów VectorStoreClient do przekazania każdego pliku z OpenAIFileClient i dodania go do Magazynu Wektorów, zachowując wynikowe odwołania do plików.

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);
}

Funkcja jest obecnie niedostępna w języku Java.

Definicja agenta

Teraz możemy utworzyć instancję OpenAIAssistantAgent. Agent jest skonfigurowany z włączonym modelem docelowym, instrukcjami i narzędziem wyszukiwania plików. Ponadto jawnie skojarzymy magazyn wektorów z narzędziem wyszukiwania plików.

Użyjemy AzureOpenAIClient ponownie w ramach tworzenia elementu OpenAIAssistantAgent:

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,
)

Funkcja jest obecnie niedostępna w języku Java.

Pętla Chat

Na koniec możemy koordynować interakcję między użytkownikiem a Agent. Zacznij od utworzenia elementu , AgentThread aby zachować stan konwersacji i utworzyć pustą pętlę.

Upewnijmy się również, że zasoby zostaną usunięte na końcu procesu, aby zminimalizować niepotrzebne opłaty.

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)

Funkcja jest obecnie niedostępna w języku Java.

Teraz przechwyć dane wejściowe użytkownika w ramach poprzedniej pętli. W takim przypadku puste dane wejściowe zostaną zignorowane, a termin EXIT będzie sygnalizować, że konwersacja zostanie ukończona.

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

Funkcja jest obecnie niedostępna w języku Java.

Przed wywołaniem odpowiedzi Agent dodajmy metodę pomocnika, aby ponownie sformatować nawiasy adnotacji Unicode do nawiasów ANSI.

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

Funkcja jest obecnie niedostępna w języku Java.

Aby wygenerować Agent odpowiedź na dane wejściowe użytkownika, wywołaj agenta, określając komunikat i wątek agenta. W tym przykładzie wybieramy strumieniową odpowiedź i przechwycimy wszystkie skojarzone adnotacje cytatów , które mają być wyświetlane na końcu cyklu odpowiedzi. Zwróć uwagę, że każdy przesyłany fragment jest formatowany ponownie przy użyciu poprzedniej metody pomocniczej.

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})"
        )

Funkcja jest obecnie niedostępna w języku Java.

Końcowa

Łącząc wszystkie kroki, mamy końcowy kod dla tego przykładu. Pełną implementację podano poniżej.

Spróbuj użyć tych sugerowanych danych wejściowych:

  1. Jaka jest liczba akapitów dla każdego scenariusza?
  2. Utwórz tabelę, która identyfikuje bohatera i antagonistę dla każdej historii.
  3. Jaki jest morał w "Białej Wężu"?
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())

W naszym repozytorium możesz znaleźć pełny kod , jak pokazano powyżej.

Funkcja jest obecnie niedostępna w języku Java.

Dalsze kroki