PromptFlow: Eintauchen in Microsofts innovative KI-Entwicklungssuite

14.02.2024Stefan Welsch
AI promptflow llm prototyping prompt engineering How-to

Banner

Prompt Flow

Heute werde ich mich einem Thema widmen, dass wahrscheinlich die wenigsten von euch kennen. Ich selbst habe es auch erst durch eine Präsentation von Microsoft kennengelernt und bin von dem, was ich gesehen habe, recht beeindruckt. Aber bei einer Präsentation sieht meistens immer alles super aus, sodass ich das Tool gerne mal selbst auf die Probe stellen wollte.

Aber was genau ist Prompt flow? Hier die Definition von Microsoft selbst

Prompt flow is a suite of development tools designed to streamline the end-to-end development cycle of LLM-based AI applications, from ideation, prototyping, testing, evaluation to production deployment and monitoring. It makes prompt engineering much easier and enables you to build LLM apps with production quality.

Zu Deutsch:

Prompt Flow ist eine Suite von Entwicklungstools, die darauf abzielt, den gesamten Entwicklungszyklus von KI-Anwendungen, die auf großen Sprachmodellen (LLMs) basieren, von der Ideenfindung, dem Prototyping, dem Testen, der Bewertung bis hin zur Produktionsbereitstellung und Überwachung zu optimieren. Es erleichtert das Prompt-Engineering erheblich und ermöglicht es Ihnen, LLM-Anwendungen mit Produktionsqualität zu erstellen.

PromptFlow ist wie bereits oben angedeutet von Microsoft und ist zum grössten Teil in Python geschrieben. Das Projekt ist noch relativ jung und sieht sehr vielversprechend aus. Aber damit genug der Theorie, wollen wir uns Promptflow doch mal in der Praxis anschauen.

Auf der Github Page von Promptflow gibt es ein YouTube Video, welches ich im Detail mal durchgespielt habe. Dieses zeigt die Verwendung von PromptFlow in Visual Studio Code. Hier gibt es ein Plugin, welches bei der Erstellung eines Projekts mit PromptFlow unterstützen soll. Die Schritte im Video sind allerdings teilweise sehr sprunghaft, sodass es bei mir teilweise zu Verwirrungen geführt hat.

Wenn ich mir die PromptFlow Extension anschaue, sehe ich, dass als Python Version hier 3.9 als recommended angegeben wird.

PromptFlow Visual Studio Code Plugin

Also die angegebene Version auf dem Mac installieren, falls noch nicht vorhanden und los gehts.

1
brew install python@3.9

Nun installiere ich mir also die Visual Studio Code Extension. Nachdem ich das gemacht habe, sehe ich ein neues Symbol in der linken Menüleiste. Wenn ich dort draufklicke, habe ich die Möglichkeit einen neuen Flow zu erstellen.

Untitled

Ich wähle im Pop-up-Fenster “Chat flow with a template” aus und gebe den Pfad zu dem Ordner an, in welchem ich den neuen Flow erstellen will.

Untitled

Wenn das erledigt ist, öffnet sich im VS Code ein neues Projekt mit der folgenden Struktur:

Untitled

Wir schauen uns die Files später noch genauer an. Laut Video soll man nun in das File flow.dag.yaml gehen und dort den Visual Editor öffnen.

Untitled

Also versuche ich wie vorgeschlagen, erstmal das Prompt flow SDK zu installieren, leider ohne Erfolg. Es erscheint die folgende Fehlermeldung:

“Error loading webview: Error: Could not register service worker”

Untitled

An der Stelle muss ich das Video abbrechen und versuche erstmal diesen Fehler zu beheben.

Kurz gegoogelt und der erste Lösungsvorschlag alle Visual Studio Code Prozesse zu killen, bringt auch schon den gewünschten Effekt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
~ ❯ ps -ef | grep "Visual Studio Code"                                                                                                                                                                                                                                            ✘ PIPE|2
  503 92460     1   0 15Jan24 ??         4:48.20 /Applications/Visual Studio Code.app/Contents/MacOS/Electron
  503 92467     1   0 15Jan24 ??         0:00.32 /Applications/Visual Studio Code.app/Contents/Frameworks/Electron Framework.framework/Helpers/chrome_crashpad_handler --no-rate-limit --monitor-self-annotation=ptype=crashpad-handler --database=/Users/swelsch/Library/Application Support/Code/Crashpad --url=appcenter://code?aid=de75e3cc-e22f-4f42-a03f-1409c21d8af8&uid=908f5b52-dad0-4b0f-b1f7-fee5f14fb27a&iid=908f5b52-dad0-4b0f-b1f7-fee5f14fb27a&sid=908f5b52-dad0-4b0f-b1f7-fee5f14fb27a --annotation=IsOfficialBuild=1 --annotation=_companyName=Microsoft --annotation=_productName=VSCode --annotation=_version=1.81.0 --annotation=exe=Electron --annotation=plat=OS X --annotation=prod=Electron --annotation=ver=22.3.18 --handshake-fd=28
  503 92468 92460   0 15Jan24 ??        51:33.40 /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (GPU).app/Contents/MacOS/Code Helper (GPU) --type=gpu-process --user-data-dir=/Users/swelsch/Library/Application Support/Code --gpu-preferences=UAAAAAAAAAAgAAAIAAAAAAAAAAAAAAAAAABgAAAAAAAwAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACgFAAAAAAAAKAUAAAAAAAC4AQAANgAAALABAAAAAAAAuAEAAAAAAADAAQAAAAAAAMgBAAAAAAAA0AEAAAAAAADYAQAAAAAAAOABAAAAAAAA6AEAAAAAAADwAQAAAAAAAPgBAAAAAAAAAAIAAAAAAAAIAgAAAAAAABACAAAAAAAAGAIAAAAAAAAgAgAAAAAAACgCAAAAAAAAMAIAAAAAAAA4AgAAAAAAAEACAAAAAAAASAIAAAAAAABQAgAAAAAAAFgCAAAAAAAAYAIAAAAAAABoAgAAAAAAAHACAAAAAAAAeAIAAAAAAACAAgAAAAAAAIgCAAAAAAAAkAIAAAAAAACYAgAAAAAAAKACAAAAAAAAqAIAAAAAAACwAgAAAAAAALgCA
  503 92470 92460   0 15Jan24 ??         0:46.38 /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper.app/Contents/MacOS/Code Helper --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-GB --service-sandbox-type=network --user-data-dir=/Users/swelsch/Library/Application Support/Code --standard-schemes=vscode-webview,vscode-file --enable-sandbox --secure-schemes=vscode-webview,vscode-file --bypasscsp-schemes --cors-schemes=vscode-webview,vscode-file --fetch-schemes=vscode-webview,vscode-file --service-worker-schemes=vscode-webview --streaming-schemes --shared-files --field-trial-handle=1718379636,r,9508796899792474748,12606522904689404813,131072 --disable-features=CalculateNativeWinOcclusion
  503 92791 92460   0 15Jan24 ??         1:00.49 /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper.app/Contents/MacOS/Code Helper --type=utility --utility-sub-type=node.mojom.NodeService --lang=en-GB --service-sandbox-type=none --user-data-dir=/Users/swelsch/Library/Application Support/Code --standard-schemes=vscode-webview,vscode-file --enable-sandbox --secure-schemes=vscode-webview,vscode-file --bypasscsp-schemes --cors-schemes=vscode-webview,vscode-file --fetch-schemes=vscode-webview,vscode-file --service-worker-schemes=vscode-webview --streaming-schemes --shared-files --field-trial-handle=1718379636,r,9508796899792474748,12606522904689404813,131072 --disable-features=CalculateNativeWinOcclusion,SpareRendererForSitePerProcess
  503 92815 92460   0 15Jan24 ??         1:17.09 /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper.app/Contents/MacOS/Code Helper --type=utility --utility-sub-type=node.mojom.NodeService --lang=en-GB --service-sandbox-type=none --user-data-dir=/Users/swelsch/Library/Application Support/Code --standard-schemes=vscode-webview,vscode-file --enable-sandbox --secure-schemes=vscode-webview,vscode-file --bypasscsp-schemes --cors-schemes=vscode-webview,vscode-file --fetch-schemes=vscode-webview,vscode-file --service-worker-schemes=vscode-webview --streaming-schemes --shared-files --field-trial-handle=1718379636,r,9508796899792474748,12606522904689404813,131072 --disable-features=CalculateNativeWinOcclusion,SpareRendererForSitePerProcess
  503 92927     1   0 15Jan24 ??         0:00.03 /Applications/Visual Studio Code.app/Contents/Frameworks/Squirrel.framework/Resources/ShipIt com.microsoft.VSCode.ShipIt /Users/swelsch/Library/Caches/com.microsoft.VSCode.ShipIt/ShipItState.plist
  503 74893 74444   0  1:35PM ttys004    0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox Visual Studio Code
~ ❯ kill -9 92460

Nun kann ich also das SDK installieren, bzw. erhalte eine Seite, auf der ich Informationen finde, was gemacht werden muss.

Wie bereits oben erwähnt habe ich erst versucht eine Virtual Environment zu nutzen. Dies blieb jedoch erfolglos und ich habe den Python Interpreter dann auf /opt/homebrew/bin/python3.9 umgestellt. Damit haben alle weitere Schritte dann erfolgreich funktioniert.

Wie erwartet öffnet sich der Visual Editor und wir sehen unseren ersten Flow.

Untitled

Nun erstellen wir uns erstmal eine Verbindung. Hierfür gibt es zwei Wege. Entweder direkt über Visual Studio Code oder per CLI(https://microsoft.github.io/promptflow/how-to-guides/manage-connections.html). Wir wollen erstmal eine über Visual Studio Code erstellen. Dafür klicken wir auf den Button “Add Connection”. Anschliessend müssen wir im Popup auswählen, ob wir OpenAI oder Azure OpenAI nutzen wollen. Ich habe keinen Azure OpenAI Account und entscheide mich also für OpenAI. Jetzt wird uns ein yaml File angezeigt, in dem wir noch den Namen der Verbindung eingeben müssen.

Untitled

Unter Zeile 15 sehen wir jetzt den Button “Create Connection” mit welchem wir die Verbindung erstellen können. Es dauert ein paar Sekunden und man sieht im Terminal, dass es einen API-Key braucht. Diesen müsst ihr euch bei OpenAI direkt erstellen (openai.com)

Sobald wir diesen eingegeben haben, erscheint unsere neue Verbindung im VisualEditor.

Untitled

Beim Klick auf die Connection müssen wir nun ein Model auswählen, mit welchem wir arbeiten wollen. Aus Kostengründen nehme ich hier mal gpt-3.5-turbo. Ihr könnt dies aber einfach nach euren Wünschen frei wählen.

Untitled

Ok wir haben nun alles so weit vorbereitet. Wollen wir also die ersten Tests mit Promptflow starten! In unserem Projektordner befindet sich eine Datei namens chat.jinja2, hier können wir unseren Prompt angeben, den wir testen wollen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
system:
You are a helpful assistant.

{% for item in chat_history %}
user:
{{item.inputs.question}}
assistant:
{{item.outputs.answer}}
{% endfor %}

user:
{{question}}

Wollen wir den System-Prompt etwas spannender gestaltet und ändern diesen wie folgt ab. Wir wollen also einen passenden Namen für ein Tier finden, welcher gut zu den Namen der Besitzer passt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
system:
Create a list of pet names that match their owners' names. 
Focus on puns, rhymes, or thematic connections that creatively link 
to the owner's name. Aim to find fitting and original names for various 
types of pets.

{% for item in chat_history %}
user:
{{item.inputs.question}}
assistant:
{{item.outputs.answer}}
{% endfor %}

user:
{{question}}

Nun gehen wir wieder auf den Visual Editor und klicken dort auf “Run it with interactive mode (text only)”

Screenshot 2024-01-26 at 14.43.43.png

Im Terminal wird promptflow nun ausgeführt und möchte eine Benutzereingabe. Ich gebe nun mal einen fiktiven Namen ein und drücke “Enter”

img_1.png

Wie wir sehen, erhalten wir ziemlich passende Namen für unsere Tierchen. ;-)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
pf flow test --flow . --inputs question='James Bond'                      4s
2024-02-06 07:58:59 +0100   34066 execution.flow     INFO     Start executing nodes in thread pool mode.
2024-02-06 07:58:59 +0100   34066 execution.flow     INFO     Start to run 2 nodes with concurrency level 16.
2024-02-06 07:58:59 +0100   34066 execution.flow     INFO     Executing node chat-gpt3.5. node run id: 75e9f4bf-3d1b-49dd-86ac-58f6a3632cb8_chat-gpt3.5_0
2024-02-06 07:58:59 +0100   34066 execution.flow     INFO     Executing node chat-gpt4. node run id: 75e9f4bf-3d1b-49dd-86ac-58f6a3632cb8_chat-gpt4_0
2024-02-06 07:59:00 +0100   34066 execution.flow     INFO     Node chat-gpt4 completes.
2024-02-06 07:59:02 +0100   34066 execution.flow     INFO     Node chat-gpt3.5 completes.
{
    "answer": "Canine Royale"
}

Nun wird sich der ein- oder andere denken: “Na toll, dass kann ich in ChatGPT auch direkt erledigen”. Stimmt, deshalb kommen wir nun zum nächsten Feature, welches ChatGPT out-of-the-box nicht mehr bietet.

Stellen wir uns vor, wir haben nun Antworten, welche wir für bestimmte Fragen erwarten. Dies ist häufig der Fall, wenn wir das allgemeine LLM mit zusätzlichen Daten füttern, kann aber auch relevant sein, wenn ich Antworten auf eine bestimmte Art und Weise forcieren will.

Will ich beispielsweise ChatGPT nutzen, um einen Chatbot rund um ein Unternehmen aufzubauen, dann erwarte ich bei einer bestimmten Benutzeranfrage auch bestimmte Antworten, bzw. spezifische unternehmens-interne Antworten, über welche das LLM nicht direkt verfügt.

Dies könnten zum Beispiel die folgenden Fragen sein:

Apple:

F: Was ist das neueste Gerät?

A: IPhone XX

Google:

F: Mit welchem Service kann ich dies und jenes umsetzen?

A: Ausgabe des spezifischen Services

b-nova:

F: Was ist das meist getrunkene Getränk bei euren Mitarbeitern?

A: Wasser 😅

Oder will ich sicherstellen, dass Antworten für bestimmte Bereiche eingegrenzt werden, dann muss ich meinen Prompt dementsprechend formulieren. Zum Beispiel:

Ich will wissen, was genau Schmetterling im Context Schwimmen bedeutet. Würde ich jetzt in ChatGPT folgendes eingeben: “Was ist Schmetterling?”, erhalte ich in etwa die folgenden Antworten:

Untitled

Ich ändere jetzt also meinen Context und gebe ChatGPT zusätzlich die Information, dass ich die Antwort gerne auf den Bereich Schwimmen reduzieren will. Hier hilft uns Promptflow nun ganz einfach weiter. Weiter oben haben wir gesehen, dass wir in der Datei chat.jinja2 einfach den System-Prompt ändern können, um unseren Chatbot mit eigenen Funktionalitäten auszustatten.

Wir ändern also unseren System-Prompt wie folgt ab und fragen die gleiche Frage wieder

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
system:
You are a chatbot that focuses exclusively on swimming.

{% for item in chat_history %}
user:
{{item.inputs.question}}
assistant:
{{item.outputs.answer}}
{% endfor %}

user:
{{question}}

Nun wollen wir unseren neuen Prompt testen. Dazu nutze ich diesmal die CLI:

1
2
3
4
5
6
7
8
9
pf flow test --flow . --inputs question='Was ist Schmetterling?'

"answer": "Der Schmetterling (auch bekannt als \"Schmetterlingsschwimmen\" 
oder \"Butterfly\") ist eine Schwimmtechnik, bei der beide Arme gleichzeitig 
über dem Wasser vor dem Körper nach vorne gestreckt werden und dann gleichzeitig 
nach unten und nach hinten geschlagen werden, während die Beine gleichzeitig 
auf und ab schlagen. Der Schmetterling ist eine anspruchsvolle Technik, die 
viel Kraft und Koordination erfordert. Es ist eine der vier offiziellen 
Schwimmtechniken, die in Wettkämpfen verwendet werden."

Wie wir sehen, gibt uns dieser Prompt die gewünschte Antwort. Wir können promptflow also wunderbar zum Prompt Engineering verwenden. Nun wollen wir im nächsten Schritt vielleicht auch noch wissen, wie hätten denn andere Modelle darauf geantwortet, oder wer gibt uns denn die präzisere Antwort auf die Frage. Stellen wir dies doch ganz unkompliziert in Promptflow mal auf gpt-4 um schauen uns die Antwort wieder an:

Untitled

1
2
3
4
5
6
7
8
pf flow test --flow . --inputs question='Was ist Schmetterling?'

"answer": "Schmetterling ist eine Schwimmtechnik im Schwimmsport, 
die auch als \"Schmetterlingsschwimmen\" bekannt ist. Es ist eine der vier 
Haupttechniken und wird oft als die anspruchsvollste angesehen. Beim 
Schmetterlingsschwimmen bewegen sich beide Arme gleichzeitig nach vorne und dann 
gleichzeitig nach hinten, während die Beine eine delfinähnliche Bewegung machen. 
Diese Technik erfordert Kraft, Koordination und Ausdauer."

Ziemlich cool, nicht wahr?

Gehen wir nun noch einen Schritt weiter. Als Nächstes wollen wir nicht nur eine einzige Frage testen, sondern direkt mehrere. Auch dazu bietet und PromptFlow eine Funktion an. Wir können per Batch direkt mehrere Abfragen machen.

Dazu erstellen wir uns eine Datei data.jsonl mit dem folgenden Inhalt:

1
2
3
{"question": "Was ist Schmetterling?"}
{"question": "Was ist Brust"}
{"question": "Was is Rücken?"}

Auch diese 3 Fragen, wollen wir nun im Context Schwimmen ausgewertet haben. Es gibt hier wieder in der UI einen Button, mit welchem wir den Run starten können (später zeige ich euch das gleiche noch per CLI, also diese Stelle merken ;-) ).

Screenshot 2024-01-28 at 14.18.32.png

Nach einem Klick erscheint ein Popup in dem wir nach der Quelle gefragt werden.

Untitled

Wenn wir auf “Local Data File” klicken, können wir die entsprechende data.jsonl Datei, die wir eben angelegt haben auswählen. Anschliessend wird eine batch_run.yaml Datei angelegt, in welchem wir noch ein Spaltenmapping angeben müssen.

Untitled

Als chat_history geben wir einfach ein leeres Array ([]) an, da wir die Chat Historie nicht verarbeiten wollen. Wenn wir die Konfiguration erledigt haben, können wir im gleichen Fenster auf “Run” klicken (also unter Zeile 10). Es öffnet sich ein Log File und der Prozess startet.

Wenn alles erfolgreich durchgelaufen ist, sehen wir auf der linken Seite unter “BATCH RUN HISTORY” einen neuen Eintrag

Untitled

Mit einem Rechtsklick können wir auf den ersten Eintrag klicken und Visualize Data auswählen.

Untitled

Es öffnet sich ein neuer Tab “Batch Run Visualization” mit der Auswertung.

Untitled

Ich finde den Weg über die UI jedoch recht unübersichtlich, deswegen zeige ich euch das gleiche nochmals per CLI. Also zurück zur Stelle, die ihr euch gemerkt habt ;-)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
> pf run create --flow . --data ./data.jsonl --column-mapping question='${data.question}' --stream

2024-01-28 14:39:29 +0100   32795 execution.bulk     INFO     Current system's available memory is 73954.921875MB, memory consumption of current process is 173.546875MB, estimated available worker count is 73954.921875/173.546875 = 426
2024-01-28 14:39:29 +0100   32795 execution.bulk     INFO     Set process count to 3 by taking the minimum value among the factors of {'default_worker_count': 4, 'row_count': 3, 'estimated_worker_count_based_on_memory_usage': 426}.
2024-01-28 14:39:29 +0100   32795 execution.bulk     INFO     Process name(SpawnProcess-2)-Process id(32809)-Line number(0) start execution.
2024-01-28 14:39:29 +0100   32795 execution.bulk     INFO     Process name(SpawnProcess-3)-Process id(32810)-Line number(1) start execution.
2024-01-28 14:39:29 +0100   32795 execution.bulk     INFO     Process name(SpawnProcess-4)-Process id(32811)-Line number(2) start execution.
2024-01-28 14:39:35 +0100   32795 execution.bulk     INFO     Process name(SpawnProcess-2)-Process id(32809)-Line number(0) completed.
2024-01-28 14:39:35 +0100   32795 execution.bulk     INFO     Finished 1 / 3 lines.
2024-01-28 14:39:35 +0100   32795 execution.bulk     INFO     Average execution time for completed lines: 6.03 seconds. Estimated time for incomplete lines: 12.06 seconds.
2024-01-28 14:39:38 +0100   32795 execution.bulk     INFO     Process name(SpawnProcess-4)-Process id(32811)-Line number(2) completed.
2024-01-28 14:39:38 +0100   32795 execution.bulk     INFO     Finished 2 / 3 lines.
2024-01-28 14:39:38 +0100   32795 execution.bulk     INFO     Average execution time for completed lines: 4.52 seconds. Estimated time for incomplete lines: 4.52 seconds.
2024-01-28 14:39:43 +0100   32795 execution.bulk     INFO     Process name(SpawnProcess-3)-Process id(32810)-Line number(1) completed.
2024-01-28 14:39:43 +0100   32795 execution.bulk     INFO     Finished 3 / 3 lines.
2024-01-28 14:39:43 +0100   32795 execution.bulk     INFO     Average execution time for completed lines: 4.68 seconds. Estimated time for incomplete lines: 0.0 seconds.
======= Run Summary =======

Run name: "new_chat_flow_created_at_2024_1_26_variant_0_20240128_143928_839454"
Run status: "Completed"
Start time: "2024-01-28 14:39:28.839431"
Duration: "0:00:17.079674"
Output path: "/Users/swelsch/.promptflow/.runs/new_chat_flow_created_at_2024_1_26_variant_0_20240128_143928_839454"

{
    "name": "new_chat_flow_created_at_2024_1_26_variant_0_20240128_143928_839454",
    "created_on": "2024-01-28T14:39:28.839431",
    "status": "Completed",
    "display_name": "new_chat_flow_created_at_2024_1_26_variant_0_20240128_143928_839454",
    "description": null,
    "tags": null,
    "properties": {
        "flow_path": "/Users/swelsch/Development/b-nova/github.com/b-nova-techhub/chatbot/my_chatbot_origin/new-chat-flow-created-at-2024-1-26",
        "output_path": "/Users/swelsch/.promptflow/.runs/new_chat_flow_created_at_2024_1_26_variant_0_20240128_143928_839454",
        "system_metrics": {
            "total_tokens": 869,
            "prompt_tokens": 158,
            "completion_tokens": 711,
            "duration": 15.282229
        }
    },
    "flow_name": "new-chat-flow-created-at-2024-1-26",
    "data": "/Users/swelsch/Development/b-nova/github.com/b-nova-techhub/chatbot/my_chatbot_origin/new-chat-flow-created-at-2024-1-26/data.jsonl",
    "output": "/Users/swelsch/.promptflow/.runs/new_chat_flow_created_at_2024_1_26_variant_0_20240128_143928_839454/flow_outputs"
}

> pf run show-details --name new_chat_flow_created_at_2024_1_26_variant_0_20240128_143701_885712

Nun können wir uns das Ergebnis des Run im Details anschauen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
> pf run show-details --name new_chat_flow_created_at_2024_1_26_variant_0_20240128_143928_839454

+----+-------------------+----------------------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|    | inputs.question   |   inputs.line_number | inputs.chat_history   | outputs.answer                                                                                                                                                                |
+====+===================+======================+=======================+===============================================================================================================================================================================+
|  0 | Was ist           |                    0 | []                    | "Schmetterling" ist das deutsche Wort für den Schwimmstil, der im Englischen als "Butterfly" bekannt ist. Es ist einer der vier Haupt-Schwimmstile neben Freistil, Rücken und |
|    | Schmetterling?    |                      |                       | Brust. Es gilt als der physisch anstrengendste und technisch anspruchsvollste Schwimmstil. Beim Schmetterlingsschwimmen werden beide Arme gleichzeitig über Wasser nach vorne |
|    |                   |                      |                       | gebracht und beide Beine führen gleichzeitig eine delfinähnliche Bewegung aus.                                                                                                |
+----+-------------------+----------------------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | Was ist Brust     |                    1 | []                    | "Brust" ist eine Schwimmtechnik, die auch als Brustschwimmen bekannt ist. Es ist eine der vier Hauptarten des Wettkampfschwimmens, neben dem Rückenschwimmen,                 |
|    |                   |                      |                       | Schmetterlingsschwimmen und Freistilschwimmen. Beim Brustschwimmen sind die Bewegungen von Armen und Beinen symmetrisch, wobei die Arme vor dem Körper gestreckt und dann     |
|    |                   |                      |                       | seitlich bis zu den Schultern geführt werden. Die Beinbewegungen ähneln dem Froschstil. Es ist bekannt, dass es eine der langsameren Schwimmtechniken ist, aber es wird oft   |
|    |                   |                      |                       | wegen seiner Stabilität und der Tatsache, dass der Schwimmer den Kopf über Wasser halten kann, bevorzugt.                                                                     |
+----+-------------------+----------------------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  2 | Was is Rücken?    |                    2 | []                    | "Rücken" ist das deutsche Wort für "Back", und im Kontext des Schwimmens bezieht es sich auf das Rückenschwimmen. Rückenschwimmen ist eine Schwimmtechnik, bei der der        |
|    |                   |                      |                       | Schwimmer auf dem Rücken schwimmt und das Gesicht nach oben richtet. Es ist eine der vier Hauptstilarten im Wettkampfschwimmen, neben Freistil, Brustschwimmen und            |
|    |                   |                      |                       | Schmetterlingsschwimmen. Es ist auch ein guter Stil für Anfänger, da der Kopf immer über Wasser ist, was das Atmen erleichtert.                                               |
+----+-------------------+----------------------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Ich finde die CLI Version zum Arbeiten und Ausprobieren schneller und intuitiver als das Visual Studio Code Plugin.

Das war mal ein erster Überblick, wie man mit PromptFlow in das Thema Prompt Engineering einsteigen kann. Natürlich geht es noch viel weiter, als das was ich euch heute im ersten Techup über das Thema gezeigt habe.

Man kann beispielsweise mehrere Nodes anlegen um verschiedene Konfigurationen und verschiedene Modelle für einen bestimmten Prompt zu testen. Ausserdem kann man sich eine Accuracy erstellen lassen, wie sehr die erwartete Antwort mit der tatsächlichen Antwort übereinstimmt.

All diese Themen sind sehr interessant und werden in einem nächsten Techup auch sicher noch einmal im Detail vorgestellt. Ich werde das Thema jedenfalls weiter im Auge behalten und dieses Framework in neue Projekte direkt einbinden. 💡

Stefan Welsch

Stefan Welsch – Manitu, Pionier, Stuntman, Mentor. Als Gründer von b-nova ist Stefan immer auf der Suche nach neuen und vielversprechenden Entwicklungsfeldern. Er ist durch und durch Pragmatiker und schreibt daher auch am liebsten Beiträge die sich möglichst nahe an 'real-world' Szenarien anlehnen.