Prompt Flow SDK のトレース機能を使用してあらゆる LLM 実行履歴を Azure AI Studio で管理する

Prompt Flow のトレース機能を使用すると、さまざまな Agent や LangChain、AutoGen、RAG などの生成 AI アプリケーションの実行プロセスを可視化できます。アプリケーション内の各ノードの入力と出力など、実行フローの詳細なビューが提供されます。

トレース機能は、Prompt Flow の OSS パッケージに実装され、[OpenTelemetry](https://opentelemetry.io/docs/specs/otel/) 仕様に従って、**使用するフレームワークに関係なく**、LLM 呼び出しまたは関数、および LangChain や AutoGen などの LLM フレームワークをトレースできるようにします。

# 準備
- VSCode　
- [Prompt flow for VS Code](https://marketplace.visualstudio.com/items?itemName=prompt-flow.prompt-flow) 拡張のインストール
- Jupyter Notebook
- `promptflow` ライブラリのインストール
    ```python
    pip install promptflow
    ```
- Azure AI Studio のトレース先を設定
    ```python
    az login
    pf config set trace.destination=azureml://subscriptions/<your_subscription_id>/resourcegroups/<your_resourcegroup_name>/providers/Microsoft.MachineLearningServices/workspaces/<your_studio_project_name>
    ```

# Hello World!!
## おまじないとコレクションの作成
```python
from promptflow.tracing import start_trace

# start a trace session, and print a url for user to check trace
start_trace(collection="trace-openai-helloworld")
```
`start_trace` するだけでトレースが開始されます。

>Starting prompt flow service...
Start prompt flow service on port xxx, version: 1.11.0.
You can stop the prompt flow service with the following command:'pf service stop'.
Alternatively, if no requests are made within 1 hours, it will automatically stop.

# Python SDK
```python
import os
from openai import AzureOpenAI

response = client.chat.completions.create(
    model="gpt-4o",
    temperature=0.7,
    max_tokens=500,
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "源実朝の趣味といえば？"},
    ]
)

print(response.choices[0].message.content)
```

**あとはいつも通り実行するだけ**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/6733ba85-43b7-1772-dfab-1910e7464834.png)

出力結果に 2 つの URL が追加されました。上がローカル UI で下が Azure AI Studio のトレース URL です。

### 自動的に Azure AI Studio に実行履歴が保存
Azure AI Studio の URL をクリックすると、Azure AI Studio のトレース画面が開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/25b9932f-058f-4951-9d28-be9b4773cf99.png)

### コレクションに実行結果が保存されていく
トレース中は意識せずに実行の度にコレクションに実行結果が追加されていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/67d70f18-0a1e-fe3d-a8ed-dca837eacf32.png)

### ローカル UI 
ローカル URL をクリックすると、ローカルサーバー上に同様の UI が表示されます。若干ローカルの方が Visualize がリッチですね。ガントチャートもあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/04a51b76-042c-b79a-b32d-d3731d40960f.png)

実行履歴の検索もできます。

https://microsoft.github.io/promptflow/how-to-guides/tracing/trace-ui.html

## AutoGen
トレース機能はフレームワークに関わらず実行できます。`start_trace` するだけ。以前検証したときのコードをそのまま使います。

https://qiita.com/nohanaga/items/e059336a54f87ff55df9

```python
start_trace(collection="autogen-groupchat")

user_proxy.initiate_chat(
    manager, message="おいしいステーキの焼き方とクロワッサンの作り方を一行で簡潔に教えてください",
    clear_history=True
)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/ddd24d5e-c8a7-367c-1510-a82b464f3a4c.png)

AutoGen 特有の複雑な内部での LLM コールが可視化されます。AutoGen の[デバッグ](https://qiita.com/nohanaga/items/e059336a54f87ff55df9#%E5%86%85%E9%83%A8%E5%87%A6%E7%90%86%E3%81%AE%E8%A7%A3%E6%9E%90)は一旦ログを SQLite database に落としてから Viewer で分析する必要がありました。

# Prompty

Build 2024 で出てきた新たなプロンプトのテンプレート形式です。ファイルはモデル構成と prompty の予想される入力を定義する多数のメタデータ フィールドを含む `yaml` 形式です。LLM 実行を設定とともに外部に分離させてある程度の再現性を持った形で CI/CD に乗っけることができます。

以下のような Prompty の立ち位置を示す図が出てきましたが、本当にシンプルな役割しか持たない仕様とのことです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/ecc937d4-938a-275f-5fbd-c479d4bde855.png)


## .prompty ファイル
```yml
---
name: Basic Prompt
description: A basic prompt that uses the chat API to answer questions
model:
    api: chat
    configuration:
        type: azure_openai
        azure_deployment: gpt-35-turbo
    parameters:
        max_tokens: 512
        temperature: 0.2
inputs:
  question:
    type: string
sample:
  "question": "Who is the most famous person in the world?"
---
system:
あなたは日本の歴史について教える教師です。
回答に自信がない場合は「すみません、わかりません。RAG を構築してください。」と回答してください。

user:
{{question}}
```

## Prompty のロード


```python
from promptflow.core import Prompty

# load prompty as a flow
f = Prompty.load(source="basic.prompty")

# execute the flow as function
result = f(question="「清水の舞台から飛び降りる」という言葉がありますが、本当に飛び降りた人は何人いますか？")
result
```

> '「清水の舞台から飛び降りる」という言葉は、...

なるほど… まぁプロンプトテンプレートはいろいろありますから、ご自分の使いやすいものをお使いいただくのが良いかと思います。

https://github.com/microsoft/promptflow/tree/main/examples/prompty

## Prompty のトレース
こちらも実行前に `start_trace` するだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/bffe3f63-6913-b2ea-8c3c-ef86043e30c9.png)

Prompty のトレース結果には変換過程の Function も入っています。

## 任意の関数
任意の関数をトレース対象にするには `@trace` を付けるだけで上のように追加できます。

```python
@trace
def my_function(input: str) -> str:
    output = input + "Hello World!"
    return output
```

# トレースの削除
```python
from promptflow.client import PFClient

pf = PFClient()
pf.traces.delete(collection="<collection-name>") 
```
Oh.. これで消えるのはローカルのみで Azure AI Studio 側のトレースを消すことができない？

# 参考
https://learn.microsoft.com/azure/ai-studio/how-to/develop/trace-local-sdk?tabs=python