Stream-Chat mit asynchronem Flex-Flow#

Verfasst von:  Avatar AvatarAuf GitHub öffnen

Lernziele - Nach Abschluss dieses Tutorials sollten Sie in der Lage sein:

  • Schreiben Sie eine LLM-Anwendung mit klassenbasiertem Flex Flow.

  • Verwenden Sie AzureOpenAIModelConfiguration als Klassen-Init-Parameter.

  • Verwenden Sie `prompty`, um Completions zu streamen.

  • Konvertieren Sie die Anwendung in einen asynchronen Flow und führen Sie einen Batch-Lauf gegen mehrere Datenzeilen durch.

  • Verwenden Sie einen klassenbasierten Flow, um den Hauptflow zu bewerten und zu lernen, wie man Aggregationen durchführt.

0. Abhängige Pakete installieren#

%%capture --no-stderr
%pip install -r ./requirements.txt

1. Verfolgen Sie Ihre Anwendung mit Prompt Flow#

Angenommen, wir haben bereits ein Python-Programm, das `prompty` nutzt.

with open("flow.py") as fin:
    print(fin.read())

Wenn stream=true in den Parametern eines Prompts konfiguriert ist, dessen Ausgabeformat Text ist, gibt das Promptflow SDK einen Generator-Typ zurück, dessen Elemente der Inhalt jedes Chunks sind.

Referenzieren Sie die OpenAI-Dokumentation, wie dies mit einfachem Python-Code durchgeführt wird: how_to_stream_completions

with open("chat.prompty") as fin:
    print(fin.read())

Erstellen Sie notwendige Verbindungen#

Verbindungen helfen bei der sicheren Speicherung und Verwaltung von geheimen Schlüsseln oder anderen sensiblen Anmeldeinformationen, die für die Interaktion mit LLMs und anderen externen Tools wie Azure Content Safety erforderlich sind.

Obiges Prompty verwendet die Verbindung open_ai_connection. Wir müssen die Verbindung einrichten, wenn wir sie noch nicht hinzugefügt haben. Nach der Erstellung wird sie in der lokalen Datenbank gespeichert und kann in jedem Flow verwendet werden.

Bereiten Sie Ihre Azure OpenAI-Ressource gemäß dieser Anleitung vor und besorgen Sie sich Ihren api_key, falls Sie noch keinen haben.

from promptflow.client import PFClient
from promptflow.connections import AzureOpenAIConnection, OpenAIConnection

# client can help manage your runs and connections.
pf = PFClient()
try:
    conn_name = "open_ai_connection"
    conn = pf.connections.get(name=conn_name)
    print("using existing connection")
except:
    # Follow https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal to create an Azure OpenAI resource.
    connection = AzureOpenAIConnection(
        name=conn_name,
        api_key="<your_AOAI_key>",
        api_base="<your_AOAI_endpoint>",
        api_type="azure",
    )

    # use this if you have an existing OpenAI account
    # connection = OpenAIConnection(
    #     name=conn_name,
    #     api_key="<user-input>",
    # )

    conn = pf.connections.create_or_update(connection)
    print("successfully created connection")

print(conn)

Visualisieren Sie den Trace mit `start_trace`#

Beachten Sie, dass wir `@trace` zur Funktion `my_llm_tool` hinzugefügt haben. Wenn Sie die folgende Zelle erneut ausführen, wird ein Trace in der Trace-Benutzeroberfläche gesammelt.

from promptflow.tracing import start_trace
from promptflow.core import AzureOpenAIModelConfiguration

from flow import ChatFlow

# create a chatFlow obj with connection
config = AzureOpenAIModelConfiguration(
    connection="open_ai_connection", azure_deployment="gpt-4o"
)
chat_flow = ChatFlow(config)

# start a trace session, and print a url for user to check trace
start_trace()

# run the flow as function, which will be recorded in the trace
result = chat_flow(question="What is ChatGPT? Please explain with detailed statement")
# note the type is async generator object as we enabled stream in prompty
result
import asyncio

# print result in stream manner
async for output in result:
    print(output, end="")
    await asyncio.sleep(0.01)
result = chat_flow(question="What is ChatGPT? Please explain with consise statement")

answer = ""
async for output in result:
    answer += output
answer

Bewerten Sie das Ergebnis#

%load_ext autoreload
%autoreload 2

import paths  # add the code_quality module to the path
from check_list import EvalFlow

eval_flow = EvalFlow(config)
# evaluate answer agains a set of statement
eval_result = eval_flow(
    answer=answer,
    statements={
        "correctness": "It contains a detailed explanation of ChatGPT.",
        "consise": "It is a consise statement.",
    },
)
eval_result

2. Führen Sie die Funktion als Flow im Batch-Lauf mit mehrzeiligen Daten aus#

Batch-Lauf mit einer Datendatei (mit mehreren Zeilen Testdaten)#

from promptflow.client import PFClient

pf = PFClient()
data = "./data.jsonl"  # path to the data file
# create run with the flow function and data
base_run = pf.run(
    flow=chat_flow,
    data=data,
    column_mapping={
        "question": "${data.question}",
        "chat_history": "${data.chat_history}",
    },
    stream=True,
)
details = pf.get_details(base_run)
details.head(10)

3. Bewerten Sie Ihren Flow#

Anschließend können Sie eine Bewertungsmethode verwenden, um Ihren Flow zu bewerten. Die Bewertungsmethoden sind ebenfalls Flows, die in der Regel LLMs verwenden, um zu überprüfen, ob die erzeugte Ausgabe bestimmten Erwartungen entspricht.

Führen Sie die Bewertung für den vorherigen Batch-Lauf durch#

Der **base_run** ist der Batch-Lauf, den wir oben in Schritt 2 abgeschlossen haben, für den Web-Klassifizierungs-Flow mit „data.jsonl“ als Eingabe.

eval_run = pf.run(
    flow=eval_flow,
    data="./data.jsonl",  # path to the data file
    run=base_run,  # specify base_run as the run you want to evaluate
    column_mapping={
        "answer": "${run.outputs.output}",
        "statements": "${data.statements}",
    },
    stream=True,
)
details = pf.get_details(eval_run)
details.head(10)
import json

metrics = pf.get_metrics(eval_run)
print(json.dumps(metrics, indent=4))
pf.visualize([base_run, eval_run])

Nächste Schritte#

Bis jetzt haben Sie Ihren Chat-Flow erfolgreich ausgeführt und bewertet. Das ist großartig!

Sie können sich weitere Beispiele ansehen

  • Stream Chat: zeigt, wie ein Chatbot erstellt wird, der im Streaming-Modus läuft.