Samouczek: część 2 — tworzenie niestandardowej aplikacji do czatu przy użyciu zestawu SDK przepływu monitów
W tym samouczku użyjesz zestawu SDK przepływu monitów (i innych bibliotek) do kompilowania, konfigurowania, oceniania i wdrażania aplikacji czatu dla firmy zajmującej się sprzedażą detaliczną o nazwie Contoso Trek. Twoja firma detaliczna specjalizuje się w sprzęcie kempingowym na świeżym powietrzu i odzieży. Aplikacja do czatu powinna odpowiadać na pytania dotyczące produktów i usług. Na przykład aplikacja do czatu może odpowiedzieć na pytania, takie jak "który namiot jest najbardziej wodoodporny?" lub "jaki jest najlepszy śpiwór do zimnej pogody?".
W tej części opisano, jak ulepszyć podstawową aplikację czatu przez dodanie rozszerzonej generacji rozszerzonej (RAG) pobierania w celu uziemienia odpowiedzi w danych niestandardowych. Pobieranie rozszerzonej generacji (RAG) to wzorzec, który używa danych z dużym modelem językowym (LLM) do generowania odpowiedzi specyficznych dla danych. Z tej części drugiej dowiesz się, jak wykonywać następujące działania:
- Wdrażanie modeli sztucznej inteligencji w usłudze Azure AI Studio do użycia w aplikacji
- Opracowywanie niestandardowego kodu RAG
- Testowanie aplikacji czatu przy użyciu przepływu monitów
Ten samouczek jest drugą częścią trzyczęściowego samouczka.
Wymagania wstępne
Kompletny samouczek: część 1 — tworzenie zasobów na potrzeby tworzenia niestandardowej aplikacji czatu przy użyciu zestawu SDK przepływu monitów.
Potrzebna jest lokalna kopia danych produktu. Repozytorium Azure-Samples/rag-data-openai-python-promptflow w witrynie GitHub zawiera przykładowe informacje o produkcie detalicznym, które są istotne dla tego scenariusza samouczka. Pobierz przykładowe dane produktów detalicznych Contoso Trek w pliku ZIP na komputer lokalny.
Struktura kodu aplikacji
Utwórz folder o nazwie rag-tutorial na komputerze lokalnym. W tej serii samouczków opisano tworzenie zawartości każdego pliku. Po ukończeniu serii samouczków struktura folderów wygląda następująco:
rag-tutorial/
│ .env
│ build_index.py
│ deploy.py
│ evaluate.py
│ eval_dataset.jsonl
| invoke-local.py
│
├───copilot_flow
│ └─── chat.prompty
| └─── copilot.py
| └─── Dockerfile
│ └─── flow.flex.yaml
│ └─── input_with_chat_history.json
│ └─── queryIntent.prompty
│ └─── requirements.txt
│
├───data
| └─── product-info/
| └─── [Your own data or sample data as described in the prerequisites.]
Implementacja w tym samouczku korzysta z elastycznego przepływu przepływu monitów, który jest podejściem code-first do implementowania przepływów. Należy określić funkcję entry (która znajduje się w copilot.py), a następnie użyć funkcji testowania, oceny i śledzenia przepływu monitów dla przepływu. Ten przepływ jest w kodzie i nie ma języka DAG (skierowanego grafu Acyklicznego) ani innego składnika wizualizacji. Dowiedz się więcej o sposobie opracowywania przepływu elastycznego w dokumentacji przepływu monitów w usłudze GitHub.
Ustawianie początkowych zmiennych środowiskowych
Istnieje kolekcja zmiennych środowiskowych używanych w różnych fragmentach kodu. Dodaj je wszystkie do pliku env .
Ważne
Jeśli utworzysz to w repozytorium git, upewnij się, że .env
znajduje się on w .gitignore
pliku, aby nie przypadkowo zaewidencjonować go w repozytorium.
Zacznij od tych wartości. W miarę postępu pracy z samouczkiem dodasz jeszcze kilka wartości.
Utwórz plik env w folderze rag-tutorial. Dodaj następujące zmienne:
AZURE_SUBSCRIPTION_ID=<your subscription id> AZURE_RESOURCE_GROUP=<your resource group> AZUREAI_PROJECT_NAME=<your project name> AZURE_OPENAI_CONNECTION_NAME=<your AIServices or Azure OpenAI connection name> AZURE_SEARCH_ENDPOINT=<your Azure Search endpoint> AZURE_SEARCH_CONNECTION_NAME=<your Azure Search connection name>
Zastąp symbole zastępcze następującymi wartościami:
Znajdź element
<your subscription id>
,<your resource group>
i<your project name>
z widoku projektu w programie AI Studio:- W programie AI Studio przejdź do projektu i wybierz pozycję Ustawienia w okienku po lewej stronie.
- W sekcji Właściwości projektu znajdź identyfikator subskrypcji i grupę zasobów. Pole Nazwa to
<your project name>
Nadal w obszarze Ustawienia projektu w sekcji Połączone zasoby zobaczysz wpis dla usługi Azure AIServices lub Azure OpenAI. Wybierz nazwę, aby otworzyć szczegóły połączenia. Nazwa połączenia zostanie wyświetlona w górnej części strony Szczegóły połączenia. Skopiuj tę nazwę do użycia dla elementu
<your AIServices or Azure OpenAI connection name>
.Wróć do strony Ustawienia projektu. W sekcji Połączone zasoby wybierz link dla usługi Azure AI Search.
- Skopiuj docelowy adres URL dla elementu
<your Azure Search endpoint>
. - Skopiuj nazwę u góry elementu
<your Azure Search connection name>
.
- Skopiuj docelowy adres URL dla elementu
Wdrażanie modeli
Potrzebujesz dwóch modeli do utworzenia aplikacji czatu opartej na usłudze RAG: modelu czatu platformy Azure OpenAI (gpt-3.5-turbo
) i modelu osadzania usługi Azure OpenAI (text-embedding-ada-002
). Wdróż te modele w projekcie usługi Azure AI Studio, korzystając z tego zestawu kroków dla każdego modelu.
Te kroki umożliwiają wdrożenie modelu w punkcie końcowym w czasie rzeczywistym z katalogu modeli programu AI Studio:
Zaloguj się do programu AI Studio i przejdź do strony głównej.
Wybierz pozycję Katalog modeli na lewym pasku bocznym.
W filtrze Kolekcje wybierz pozycję Azure OpenAI.
Wybierz model z kolekcji Azure OpenAI. Po raz pierwszy wybierz
gpt-3.5-turbo
model. Po raz drugi wybierztext-embedding-ada-002
model.Wybierz pozycję Wdróż , aby otworzyć okno wdrażania.
Wybierz koncentrator, do którego chcesz wdrożyć model. Użyj tego samego centrum co projekt.
Określ nazwę wdrożenia i zmodyfikuj inne ustawienia domyślne w zależności od wymagań.
Wybierz Wdróż.
Zostanie wyświetlona strona szczegółów wdrożenia. Wybierz pozycję Otwórz na placu zabaw.
Wybierz pozycję Wyświetl kod , aby uzyskać przykłady kodu, których można użyć do korzystania z wdrożonego modelu w aplikacji.
Podczas wdrażania gpt-3.5-turbo
modelu znajdź następujące wartości w sekcji Wyświetl kod i dodaj je do pliku env :
AZURE_OPENAI_ENDPOINT=<endpoint_value>
AZURE_OPENAI_CHAT_DEPLOYMENT=<chat_model_deployment_name>
AZURE_OPENAI_API_VERSION=<api_version>
Podczas wdrażania text-embedding-ada-002
modelu dodaj nazwę do pliku env :
AZURE_OPENAI_EMBEDDING_DEPLOYMENT=<embedding_model_deployment_name>
Instalowanie interfejsu wiersza polecenia platformy Azure i logowanie
Zainstaluj interfejs wiersza polecenia platformy Azure i zaloguj się z lokalnego środowiska deweloperskiego, aby można było wywołać usługę Azure OpenAI przy użyciu poświadczeń użytkownika.
W większości przypadków można zainstalować interfejs wiersza polecenia platformy Azure z poziomu terminalu przy użyciu następującego polecenia:
Możesz postępować zgodnie z instrukcjami Instalowanie interfejsu wiersza polecenia platformy Azure, jeśli te polecenia nie działają w konkretnym systemie operacyjnym lub konfiguracji.
Po zainstalowaniu interfejsu wiersza polecenia platformy Azure zaloguj się przy użyciu az login
polecenia i zaloguj się przy użyciu przeglądarki:
az login
Teraz utworzymy naszą aplikację i wywołamy usługę Azure OpenAI Service z poziomu kodu.
Tworzenie nowego środowiska języka Python
Najpierw musimy utworzyć nowe środowisko języka Python, za pomocą których można zainstalować pakiety zestawu SDK przepływu monitu. Nie instaluj pakietów w globalnej instalacji języka Python. Zawsze należy używać środowiska wirtualnego lub conda podczas instalowania pakietów języka Python. W przeciwnym razie możesz przerwać globalną instalację języka Python.
W razie potrzeby zainstaluj język Python
Zalecamy używanie języka Python w wersji 3.10 lub nowszej, ale wymagana jest co najmniej wersja python 3.8. Jeśli nie masz zainstalowanej odpowiedniej wersji języka Python, możesz postępować zgodnie z instrukcjami w samouczku języka Python programu VS Code, aby uzyskać najprostszy sposób instalowania języka Python w systemie operacyjnym.
Utworzenie środowiska wirtualnego
Jeśli masz już zainstalowany język Python w wersji 3.10 lub nowszej, możesz utworzyć środowisko wirtualne przy użyciu następujących poleceń:
Aktywowanie środowiska języka Python oznacza, że po uruchomieniu python
lub pip
w wierszu polecenia należy użyć interpretera języka Python zawartego .venv
w folderze aplikacji.
Uwaga
Możesz użyć deactivate
polecenia , aby zamknąć środowisko wirtualne języka Python i później ponownie aktywować je w razie potrzeby.
Uaktualnianie narzędzia pip
Aby upewnić się, że masz najnowszą wersję narzędzia, uruchom następujące polecenie:
python -m pip install --upgrade pip
Instalowanie zestawu SDK przepływu monitów
Przepływ monitów to zestaw narzędzi programistycznych zaprojektowanych w celu usprawnienia kompleksowego cyklu tworzenia aplikacji sztucznej inteligencji opartych na usłudze LLM, od ideacji, tworzenia prototypów, testowania, oceny, wdrażania produkcyjnego i monitorowania.
Użyj narzędzia, aby zainstalować zestaw SDK przepływu monitów w utworzonym środowisku wirtualnym.
pip install promptflow
pip install azure-identity
Zestaw SDK przepływu monitów przyjmuje zależność od wielu pakietów, które można wybrać oddzielnie zainstalować, jeśli nie chcesz ich wszystkich:
promptflow-core
: zawiera podstawowe środowisko uruchomieniowe przepływu monitów używane do wykonywania kodu LLMpromptflow-tracing
: uproszczona biblioteka używana do emitowania śladów OpenTelemetry w standardachpromptflow-devkit
: zawiera narzędzia do testowania przepływu monitów i przeglądarki śledzenia dla lokalnych środowisk deweloperskichopenai
: biblioteki klienta do korzystania z usługi Azure OpenAIpython-dotenv
: służy do ustawiania zmiennych środowiskowych przez odczytywanie ich z.env
plików
Tworzenie indeksu usługi Azure AI Search
Celem tej aplikacji opartej na usłudze RAG jest uziemienie odpowiedzi modelu w danych niestandardowych. Używasz indeksu usługi Azure AI Search, który przechowuje wektoryzowane dane z modelu osadzania. Indeks wyszukiwania służy do pobierania odpowiednich dokumentów na podstawie pytania użytkownika.
Jeśli nie masz jeszcze utworzonego indeksu usługi Azure AI Search, omówimy sposób jej tworzenia. Jeśli masz już indeks do użycia, możesz przejść do sekcji ustawienia zmiennej środowiskowej wyszukiwania. Indeks wyszukiwania jest tworzony w usłudze Azure AI usługa wyszukiwania, do którego utworzono lub odwołuje się w poprzednim kroku.
Użyj własnych danych lub pobierz przykładowe dane produktu firmy Contoso Trek w pliku ZIP na komputerze lokalnym. Rozpakuj plik do folderu rag-tutorial/data . Te dane są kolekcją plików markdown reprezentujących informacje o produkcie. Dane są ustrukturyzowane w sposób łatwy do pozyskiwania do indeksu wyszukiwania. Utworzysz indeks wyszukiwania na podstawie tych danych.
Pakiet RAG przepływu monitu umożliwia pozyskiwanie plików markdown, lokalne tworzenie indeksu wyszukiwania i rejestrowanie go w projekcie w chmurze. Zainstaluj pakiet RAG przepływu monitu:
pip install promptflow-rag
Utwórz plik build_index.py w folderze rag-tutorial.
Skopiuj i wklej następujący kod do pliku build_index.py .
import os from dotenv import load_dotenv load_dotenv() from azure.ai.ml import MLClient from azure.identity import DefaultAzureCredential from azure.ai.ml.entities import Index from promptflow.rag.config import ( LocalSource, AzureAISearchConfig, EmbeddingsModelConfig, ConnectionConfig, ) from promptflow.rag import build_index client = MLClient( DefaultAzureCredential(), os.getenv("AZURE_SUBSCRIPTION_ID"), os.getenv("AZURE_RESOURCE_GROUP"), os.getenv("AZUREAI_PROJECT_NAME"), ) import os # append directory of the current script to data directory script_dir = os.path.dirname(os.path.abspath(__file__)) data_directory = os.path.join(script_dir, "data/product-info/") # Check if the directory exists if os.path.exists(data_directory): files = os.listdir(data_directory) # List all files in the directory if files: print( f"Data directory '{data_directory}' exists and contains {len(files)} files." ) else: print(f"Data directory '{data_directory}' exists but is empty.") exit() else: print(f"Data directory '{data_directory}' does not exist.") exit() index_name = "tutorial-index" # your desired index name index_path = build_index( name=index_name, # name of your index vector_store="azure_ai_search", # the type of vector store - in this case it is Azure AI Search. Users can also use "azure_cognitive search" embeddings_model_config=EmbeddingsModelConfig( model_name=os.getenv("AZURE_OPENAI_EMBEDDING_DEPLOYMENT"), deployment_name=os.getenv("AZURE_OPENAI_EMBEDDING_DEPLOYMENT"), connection_config=ConnectionConfig( subscription_id=client.subscription_id, resource_group_name=client.resource_group_name, workspace_name=client.workspace_name, connection_name=os.getenv("AZURE_OPENAI_CONNECTION_NAME"), ), ), input_source=LocalSource(input_data=data_directory), # the location of your files index_config=AzureAISearchConfig( ai_search_index_name=index_name, # the name of the index store inside the azure ai search service ai_search_connection_config=ConnectionConfig( subscription_id=client.subscription_id, resource_group_name=client.resource_group_name, workspace_name=client.workspace_name, connection_name=os.getenv("AZURE_SEARCH_CONNECTION_NAME"), ), ), tokens_per_chunk=800, # Optional field - Maximum number of tokens per chunk token_overlap_across_chunks=0, # Optional field - Number of tokens to overlap between chunks ) # register the index so that it shows up in the cloud project client.indexes.create_or_update(Index(name=index_name, path=index_path))
- Ustaw zmienną
index_name
na nazwę żądanego indeksu. - W razie potrzeby możesz zaktualizować zmienną
path_to_data
do ścieżki, w której są przechowywane pliki danych.
Ważne
Domyślnie przykładowy kod oczekuje struktury kodu aplikacji zgodnie z opisem wcześniej w tym samouczku. Folder
data
powinien być na tym samym poziomie co build_index.py i pobranyproduct-info
folder z plikami md w nim.- Ustaw zmienną
W konsoli uruchom kod, aby utworzyć indeks lokalnie i zarejestrować go w projekcie chmury:
python build_index.py
Po uruchomieniu skryptu możesz wyświetlić nowo utworzony indeks na stronie Indeksy projektu usługi Azure AI Studio. Aby uzyskać więcej informacji, zobacz How to build and consume vector indexes in Azure AI Studio (Jak tworzyć i wykorzystywać indeksy wektorów w usłudze Azure AI Studio).
Jeśli ponownie uruchomisz skrypt o tej samej nazwie indeksu, zostanie utworzona nowa wersja tego samego indeksu.
Ustawianie zmiennej środowiskowej indeksu wyszukiwania
Gdy masz nazwę indeksu, której chcesz użyć (tworząc nowy lub odwołując się do istniejącego), dodaj ją do pliku env w następujący sposób:
AZUREAI_SEARCH_INDEX_NAME=<index-name>
Opracowywanie niestandardowego kodu RAG
Następnie utworzysz kod niestandardowy, aby dodać możliwości rozszerzonej generacji (RAG) pobierania do podstawowej aplikacji czatu. W przewodniku Szybki start utworzono pliki chat.py i chat.prompty . W tym miejscu rozszerzysz ten kod, aby uwzględnić możliwości RAG.
Aplikacja do czatu z narzędziem RAG implementuje następującą ogólną logikę:
- Generowanie zapytania wyszukiwania na podstawie intencji zapytania użytkownika i historii czatów
- Osadzanie zapytania przy użyciu modelu osadzania
- Pobieranie odpowiednich dokumentów z indeksu wyszukiwania, biorąc pod uwagę zapytanie
- Przekazywanie odpowiedniego kontekstu do modelu uzupełniania czatu usługi Azure OpenAI
- Zwraca odpowiedź z modelu Azure OpenAI
Logika implementacji aplikacji czatu
Logika implementacji aplikacji czatu znajduje się w pliku copilot.py . Ten plik zawiera podstawową logikę aplikacji czatu opartej na programie RAG.
Utwórz folder o nazwie copilot_flow w folderze rag-tutorial .
Następnie utwórz plik o nazwie copilot.py w folderze copilot_flow .
Dodaj następujący kod do pliku copilot.py :
import os from dotenv import load_dotenv load_dotenv() from promptflow.core import Prompty, AzureOpenAIModelConfiguration from promptflow.tracing import trace from openai import AzureOpenAI # <get_documents> @trace def get_documents(search_query: str, num_docs=3): from azure.identity import DefaultAzureCredential, get_bearer_token_provider from azure.search.documents import SearchClient from azure.search.documents.models import VectorizedQuery token_provider = get_bearer_token_provider( DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default" ) index_name = os.getenv("AZUREAI_SEARCH_INDEX_NAME") # retrieve documents relevant to the user's question from Cognitive Search search_client = SearchClient( endpoint=os.getenv("AZURE_SEARCH_ENDPOINT"), credential=DefaultAzureCredential(), index_name=index_name, ) aoai_client = AzureOpenAI( azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"), azure_ad_token_provider=token_provider, api_version=os.getenv("AZURE_OPENAI_API_VERSION"), ) # generate a vector embedding of the user's question embedding = aoai_client.embeddings.create( input=search_query, model=os.getenv("AZURE_OPENAI_EMBEDDING_DEPLOYMENT") ) embedding_to_query = embedding.data[0].embedding context = "" # use the vector embedding to do a vector search on the index vector_query = VectorizedQuery( vector=embedding_to_query, k_nearest_neighbors=num_docs, fields="contentVector" ) results = trace(search_client.search)( search_text="", vector_queries=[vector_query], select=["id", "content"] ) for result in results: context += f"\n>>> From: {result['id']}\n{result['content']}" return context # <get_documents> from promptflow.core import Prompty, AzureOpenAIModelConfiguration from pathlib import Path from typing import TypedDict class ChatResponse(TypedDict): context: dict reply: str def get_chat_response(chat_input: str, chat_history: list = []) -> ChatResponse: model_config = AzureOpenAIModelConfiguration( azure_deployment=os.getenv("AZURE_OPENAI_CHAT_DEPLOYMENT"), api_version=os.getenv("AZURE_OPENAI_API_VERSION"), azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"), ) searchQuery = chat_input # Only extract intent if there is chat_history if len(chat_history) > 0: # extract current query intent given chat_history path_to_prompty = f"{Path(__file__).parent.absolute().as_posix()}/queryIntent.prompty" # pass absolute file path to prompty intentPrompty = Prompty.load( path_to_prompty, model={ "configuration": model_config, "parameters": { "max_tokens": 256, }, }, ) searchQuery = intentPrompty(query=chat_input, chat_history=chat_history) # retrieve relevant documents and context given chat_history and current user query (chat_input) documents = get_documents(searchQuery, 3) # send query + document context to chat completion for a response path_to_prompty = f"{Path(__file__).parent.absolute().as_posix()}/chat.prompty" chatPrompty = Prompty.load( path_to_prompty, model={ "configuration": model_config, "parameters": {"max_tokens": 256, "temperature": 0.2}, }, ) result = chatPrompty( chat_history=chat_history, chat_input=chat_input, documents=documents ) return dict(reply=result, context=documents)
Plik copilot.py zawiera dwie kluczowe funkcje: get_documents()
i get_chat_response()
.
Zwróć uwagę, że te dwie funkcje mają @trace
dekorator, który umożliwia wyświetlenie dzienników śledzenia przepływu monitów poszczególnych danych wejściowych i wyjściowych wywołań funkcji. @trace
jest alternatywnym i rozszerzonym podejściem do sposobu, w jaki przewodnik Szybki start przedstawia możliwości śledzenia.
Funkcja get_documents()
jest rdzeniem logiki RAG.
- Pobiera zapytanie wyszukiwania i liczbę dokumentów do pobrania.
- Osadza zapytanie wyszukiwania przy użyciu modelu osadzania.
- Wysyła zapytanie do indeksu usługi Azure Search, aby pobrać dokumenty istotne dla zapytania.
- Zwraca kontekst dokumentów.
Funkcja get_chat_response()
kompiluje się z poprzedniej logiki w pliku chat.py :
- Przyjmuje element i
chat_input
dowolnychat_history
element . - Tworzy zapytanie wyszukiwania na
chat_input
podstawie intencji ichat_history
. - Wywołuje metodę
get_documents()
pobierania odpowiednich dokumentów. - Wywołuje model uzupełniania czatu z kontekstem, aby uzyskać uziemiony odpowiedź na zapytanie.
- Zwraca odpowiedź i kontekst. Ustawiamy słownik wpisany jako obiekt zwracany dla naszej
get_chat_response()
funkcji. Możesz wybrać sposób, w jaki kod zwraca odpowiedź, aby najlepiej dopasować swój przypadek użycia.
Funkcja get_chat_response()
używa dwóch Prompty
plików, aby wykonać niezbędne wywołania modelu dużego języka (LLM), które omówimy w następnej kolejności.
Monituj o szablon czatu
Plik chat.prompty jest prosty i podobny do chat.prompty w przewodniku Szybki start. Monit systemowy jest aktualizowany w celu odzwierciedlenia naszego produktu, a szablony monitów zawierają kontekst dokumentu.
Dodaj plik chat.prompty w katalogu copilot_flow . Plik reprezentuje wywołanie modelu uzupełniania czatu z podanym monitem systemowym, historią czatu i kontekstem dokumentu.
Dodaj ten kod do pliku chat.prompty :
--- name: Chat Prompt description: A prompty that uses the chat API to respond to queries grounded in relevant documents model: api: chat configuration: type: azure_openai inputs: chat_input: type: string chat_history: type: list is_chat_history: true default: [] documents: type: object --- system: You are an AI assistant helping users with queries related to outdoor outdooor/camping gear and clothing. If the question is not related to outdoor/camping gear and clothing, just say 'Sorry, I only can answer queries related to outdoor/camping gear and clothing. So, how can I help?' Don't try to make up any answers. If the question is related to outdoor/camping gear and clothing but vague, ask for clarifying questions instead of referencing documents. If the question is general, for example it uses "it" or "they", ask the user to specify what product they are asking about. Use the following pieces of context to answer the questions about outdoor/camping gear and clothing as completely, correctly, and concisely as possible. Do not add documentation reference in the response. # Documents {{documents}} {% for item in chat_history %} {{item.role}} {{item.content}} {% endfor %} user: {{chat_input}}
Monituj szablon historii czatów
Ponieważ wdrażamy aplikację opartą na programie RAG, istnieje dodatkowa logika wymagana do pobierania odpowiednich dokumentów nie tylko dla bieżącego zapytania użytkownika, ale także z uwzględnieniem historii czatów. Bez tej dodatkowej logiki połączenie LLM będzie uwzględniać historię czatów. Ale nie pobrano odpowiednich dokumentów dla tego kontekstu, więc nie otrzymasz oczekiwanej odpowiedzi.
Jeśli na przykład użytkownik zadaje pytanie "czy jest wodoodporny?", potrzebujemy systemu, aby przyjrzeć się historii czatów, aby określić, do czego odnosi się słowo "it" i uwzględnić ten kontekst w zapytaniu wyszukiwania do osadzenia. W ten sposób pobieramy odpowiednie dokumenty dla "go" (być może namiot Alpine Explorer) i jego "koszt".
Zamiast przekazywać tylko zapytanie użytkownika do osadzenia, musimy wygenerować nowe zapytanie wyszukiwania, które uwzględnia dowolną historię czatów. Używamy innego Prompty
(czyli innego wywołania LLM) z określonym monitem o interpretację intencji zapytania użytkownika danej historii czatu i konstruowania zapytania wyszukiwania, które ma wymagany kontekst.
Utwórz plik queryIntent.prompty w folderze copilot_flow .
Wprowadź ten kod, aby uzyskać szczegółowe informacje o formacie monitu i przykładach z kilkoma zrzutami.
--- name: Chat Prompt description: A prompty that extract users query intent based on the current_query and chat_history of the conversation model: api: chat configuration: type: azure_openai inputs: query: type: string chat_history: type: list is_chat_history: true default: [] --- system: - You are an AI assistant reading a current user query and chat_history. - Given the chat_history, and current user's query, infer the user's intent expressed in the current user query. - Once you infer the intent, respond with a search query that can be used to retrieve relevant documents for the current user's query based on the intent - Be specific in what the user is asking about, but disregard parts of the chat history that are not relevant to the user's intent. Example 1: With a chat_history like below: \``` chat_history: [ { "role": "user", "content": "are the trailwalker shoes waterproof?" }, { "role": "assistant", "content": "Yes, the TrailWalker Hiking Shoes are waterproof. They are designed with a durable and waterproof construction to withstand various terrains and weather conditions." } ] \``` User query: "how much do they cost?" Intent: "The user wants to know how much the Trailwalker Hiking Shoes cost." Search query: "price of Trailwalker Hiking Shoes" Example 2: With a chat_history like below: \``` chat_history: [ { "role": "user", "content": "are the trailwalker shoes waterproof?" }, { "role": "assistant", "content": "Yes, the TrailWalker Hiking Shoes are waterproof. They are designed with a durable and waterproof construction to withstand various terrains and weather conditions." }, { "role": "user", "content": "how much do they cost?" }, { "role": "assistant", "content": "The TrailWalker Hiking Shoes are priced at $110." }, { "role": "user", "content": "do you have waterproof tents?" }, { "role": "assistant", "content": "Yes, we have waterproof tents available. Can you please provide more information about the type or size of tent you are looking for?" }, { "role": "user", "content": "which is your most waterproof tent?" }, { "role": "assistant", "content": "Our most waterproof tent is the Alpine Explorer Tent. It is designed with a waterproof material and has a rainfly with a waterproof rating of 3000mm. This tent provides reliable protection against rain and moisture." } ] \``` User query: "how much does it cost?" Intent: "the user would like to know how much the Alpine Explorer Tent costs" Search query: "price of Alpine Explorer Tent" {% for item in chat_history %} {{item.role}} {{item.content}} {% endfor %} Current user query: {{query}} Search query:
Prosty komunikat systemowy w naszym pliku queryIntent.prompty osiąga minimum wymagane przez rozwiązanie RAG do pracy z historią czatów.
Konfigurowanie wymaganych pakietów
Utwórz requirements.txt pliku w folderze copilot_flow. Dodaj tę zawartość:
openai
azure-identity
azure-search-documents==11.4.0
promptflow[azure]==1.11.0
promptflow-tracing==1.11.0
promptflow-tools==1.4.0
promptflow-evals==0.3.0
jinja2
aiohttp
python-dotenv
Te pakiety są wymagane, aby przepływ był uruchamiany lokalnie i w wdrożonym środowisku.
Korzystanie z przepływu flex
Jak wspomniano wcześniej, ta implementacja korzysta z elastycznego przepływu przepływu monitów, czyli podejścia opartego na kodzie do implementowania przepływów. Należy określić funkcję entry (zdefiniowaną w copilot.py). Dowiedz się więcej na temat opracowywania elastycznego przepływu.
Ten plik yaml określa funkcję entry, która jest funkcją zdefiniowaną get_chat_response
w pliku copilot.py
. Określa również wymagania, które należy uruchomić przepływ.
Utwórz plik flow.flex.yaml w folderze copilot_flow . Dodaj tę zawartość:
entry: copilot:get_chat_response
environment:
python_requirements_txt: requirements.txt
Testowanie aplikacji czatu przy użyciu przepływu monitów
Użyj możliwości testowania przepływu monitów, aby zobaczyć, jak aplikacja czatu działa zgodnie z oczekiwaniami w przykładowych danych wejściowych. Korzystając z pliku flow.flex.yaml , możesz użyć przepływu monitów do przetestowania przy użyciu określonych danych wejściowych.
Uruchom przepływ przy użyciu tego polecenia przepływu wiersza polecenia:
pf flow test --flow ./copilot_flow --inputs chat_input="how much do the Trailwalker shoes cost?"
Alternatywnie możesz uruchomić przepływ interaktywnie z flagą --ui
.
pf flow test --flow ./copilot_flow --ui
W przypadku korzystania z usługi --ui
środowisko interaktywnego przykładowego czatu otwiera okno w przeglądarce lokalnej.
- Przy pierwszym uruchomieniu z flagą
--ui
należy ręcznie wybrać dane wejściowe i wyjściowe czatu z opcji. Po pierwszym utworzeniu tej sesji wybierz ustawienia konfiguracji pola Dane wejściowe/wyjściowe czatu, a następnie rozpocznij rozmowę. - Przy następnym uruchomieniu z flagą
--ui
sesja zapamięta ustawienia.
Po zakończeniu sesji interakcyjnej wprowadź Ctrl + C w oknie terminalu, aby zatrzymać serwer.
Testowanie za pomocą historii czatów
Ogólnie rzecz biorąc, przepływ monitów i Prompty
historia czatów pomocy technicznej. Jeśli testujesz z flagą --ui
w lokalnym obsługiwanym frontonie, przepływ monitu zarządza historią czatu. Jeśli testujesz bez --ui
elementu , możesz określić plik wejściowy zawierający historię czatów.
Ponieważ nasza aplikacja implementuje aplikację RAG, musieliśmy dodać dodatkową logikę do obsługi historii czatów w pliku queryIntent.prompty .
Aby przetestować historię czatów, utwórz plik o nazwie input_with_chat_history.json w folderze copilot_flow i wklej następującą zawartość:
{
"chat_input": "how much does it cost?",
"chat_history": [
{
"role": "user",
"content": "are the trailwalker shoes waterproof?"
},
{
"role": "assistant",
"content": "Yes, the TrailWalker Hiking Shoes are waterproof. They are designed with a durable and waterproof construction to withstand various terrains and weather conditions."
},
{
"role": "user",
"content": "how much do they cost?"
},
{
"role": "assistant",
"content": "The TrailWalker Hiking Shoes are priced at $110."
},
{
"role": "user",
"content": "do you have waterproof tents?"
},
{
"role": "assistant",
"content": "Yes, we have waterproof tents available. Can you please provide more information about the type or size of tent you are looking for?"
},
{
"role": "user",
"content": "which is your most waterproof tent?"
},
{
"role": "assistant",
"content": "Our most waterproof tent is the Alpine Explorer Tent. It is designed with a waterproof material and has a rainfly with a waterproof rating of 3000mm. This tent provides reliable protection against rain and moisture."
}
]
}
Aby przetestować ten plik, uruchom polecenie:
pf flow test --flow ./copilot_flow --inputs ./copilot_flow/input_with_chat_history.json
Oczekiwane dane wyjściowe są podobne do: "Namiot Alpine Explorer jest wyceniany na 350 dolarów."
Ten system jest w stanie interpretować intencję zapytania "ile kosztuje?", aby wiedzieć, że "on" odnosi się do namiotu Alpine Explorer, który był najnowszym kontekstem w historii czatów. Następnie system tworzy zapytanie wyszukiwania dla ceny namiotu Alpine Explorer, aby pobrać odpowiednie dokumenty dla kosztu namiotu Alpine Explorer i otrzymamy odpowiedź.
Jeśli przejdziesz do śledzenia z tego przebiegu przepływu, zobaczysz konwersację w akcji. Link śledzenia lokalnego jest wyświetlany w danych wyjściowych konsoli przed wynikiem przebiegu testu przepływu.
Czyszczenie zasobów
Aby uniknąć niepotrzebnych kosztów platformy Azure, usuń zasoby utworzone w tym samouczku, jeśli nie są już potrzebne. Aby zarządzać zasobami, możesz użyć witryny Azure Portal.
Ale nie usuwaj ich jeszcze, jeśli chcesz wdrożyć aplikację czatu na platformie Azure w następnej części tej serii samouczków.