Arize を使った Langflow の Observability

# エージェントの動作を可視化したい

前回 Langflow と Amazon Nova Canvas を使って、画像生成できるアプリをノーコードで作ってみましたが、エージェントに使うモデルやプロンプトによっては、期待した通りに動いてくれなかったりしました。具体的には、作成した画像を指示通りにアップロードしなかったりしました。

https://qiita.com/harusamet/items/7310d5983dab8f1a4b8a

Langflow をローカルで実行していればエージェントの動きはコンソール上に標準出力されますが、ちょっと見づらいです。1回の試行でも以下のような感じで数百行のログが出ることも。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/9281a4ba-a471-478c-9054-9681937ab853.png)

こんなときは、ログをいい感じで見やすくしてくれる Observability のツールを利用するとわかりやすくなります。Langflow は Arize と統合されているので、ログの転送が簡単に行えます。Arize のサービスの一つ Arize Phonenix の画面は以下のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/f37055c6-b06b-439e-8294-3ec7c628de74.png)

Agent Executor が Template を受け取って Bedrock を実行して...みたいな実行手順は左側に見え、右側には Input や Output が見えるので Agent の中間出力（思考過程のようなもの）を見ることができます。変な挙動がないかチェックしやすいです。

# Arize のサービスと機能

Arize で提供されるサービスやデプロイ方法などによって設定方法が違います。Arize は最初に OSS の Arize Phoenix を開発し、それを Enterprise version の SaaS として開発・提供しているようです。

https://docs.arize.com/phoenix/resources#what-is-the-difference-between-phoenix-and-arize

完全に理解していないところもありますが、Langflow との統合の観点で、自分なりに整理すると以下に分けられます。また Arize AX とArize Phoenix (Saas) では、アカウントは別になるようです。

|名前|特徴|Langflowとの統合|
|--|--|--|
|Arize AX|エンタープライズ向けの Observability ツール|プロジェクトの Space ID と API Key を指定して自動連携|
|Arize Phoenix (Saas) | Open Source の Observability ツールで開発・テストなどで利用。SaaS で運用管理不要。|API Key で自動連携|
|Arize Phoenix (Self-host)| Self-host 版で、実行する環境を用意してデプロイして利用する。| ホストの URL を指定して実装|

Arize の機能としては主に以下が提供されています。

- エージェント評価
    エージェントの挙動が想定したものかどうかを評価します。例えばタスクに対して正しいツールを実行しているか、実行回数は十分か、ツールの実行結果は正確か、などです。
- 追跡 (Tracing)
    LLM アプリケーションやエージェントの実行フローを詳細に記録し、可視化する機能です。アプリケーションの各ステップ (Span と呼ぶ) を追跡して、問題の特定やデバッグを容易にします。上に掲載した Phonenix の画像は Tracing の様子を表しており、左側のツリーの一つ一つのステップが span です。
 
- (全体の) 評価
    エージェントの個々の評価でなく、それらがすべての処理を終えたあとの最終出力の品質を評価します。

この記事ではとりあえず Tracing をやります。

# Arize 側の設定

SaaS で利用する場合はアカウントをセットアップして API Key などを取得するところまで行います。もし Self-host にする場合は、追加で Docker などを使って手元にデプロイする必要があります。

## Arize AX

アカウントを作ってログインすると、最初は所属する Organization のなかで自分が利用する Space を作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/3ce44f7e-e517-4f0a-ba26-25ad05cb619b.png)

以下は DataStax の Organization のなかに DataStax という Space を作って選択した画面です。左のメニューから Settings で API Key を生成できます。この先の画面で確認できる **Space ID** と **API Key** を使って Langflow から Agent のログを転送できます。Space を作成する際に Admin 権限でユーザを追加しないと API Key の生成ができなかったりしますので、Admin で追加しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/fddc6f8e-fbbc-4aa4-aae7-1548375be9d9.png)

## Arize Phoenix (SaaS)

Arize Phoenix は個人向けなので Organization や Space といった考え方がなく **API Key** 一つで使えます。

ログイン後に左下の鍵マークをクリックすると API Key の画面になります。これをコピーして使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/7b5eb387-baff-431c-abbb-88e5bfbf4c0e.png)

## Arize Phoenix (Self-host)

Self-host 版は、機能をすぐに試せるようにということで、デフォルトでは認証無しで利用できるようになっています。認証は設定次第で追加もできますが、今回は認証無しで進めます。その場合は、ホスト先の URL のみが必要です。

https://docs.arize.com/phoenix/self-hosting/authentication


それでは Self-host していきます。Docker か Kubernetes を選べるのですが、お試しということで Docker を手元の PC で実行することにします。手順はこちらに記載があります。

https://docs.arize.com/phoenix/self-hosting/deployment-options/docker

I. 手元に Docker 環境を準備
II. Docker イメージを取得
```shell
docker pull arizephoenix/phoenix
```
III. 実行
```shell
docker run -p 6006:6006 -p 4317:4317 -i -t arizephoenix/phoenix:latest
```

そうすると [http://0.0.0.0:6006/](http://0.0.0.0:6006/) でアクセスできるようになります。画面は以下のような感じで SaaS 版とほぼ同じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/1b285741-f84f-4004-bcd2-01f2f8f4df0c.png)

# Langflow 側の設定

## Arize AX と Arise Phoenix (SaaS版)の場合
SaaS で使える Arize AX と Arise Phoenix (SaaS版) は、API Key などを記載した `.env` ファイルを作成して Langflow を実行すれば、Langflow のエージェントのログが自動的に転送されます。Langflow のフローの名前と同じ project が自動的に Arize 側に作成され、ログは project ごとに格納されます。例えば、以下のように全部指定しておくと、Arize AX と Arise Phoenix (SaaS版)の双方に送信されます。

```json
ARIZE_SPACE_ID=""
ARIZE_API_KEY=""
PHOENIX_API_KEY=""
```
ファイルを`env/.env` に置いた場合は、以下のようにファイルを指定して Langflow を実行します。
```shell
uv run langflow run --env-file env/.env
```

## Arise Phoenix (Self-host 版)の場合

Self-host 版の Arise Phoenix の場合は、フローの最初のブロックに以下のようなpythonコードを Langflow コンポーネントの class の外に挿入して、Tracer を初期化します。`project_name`でArize側の project の名前を指定します。auto_instrument を True にすることによって、Arize が LLM や Langchain などを自動検知して、これらをトレースします。endpoint はself-hostしたURLを指定します。
返り値のtracer_provider は使わなくても動きますが、もしTraceの内容をカスタムしたい場合はこれを使います。

```python
from phoenix.otel import register
# configure the Phoenix tracer
tracer_provider = register(
  project_name="Amazon-nova-canvas-demo", # Default is 'default'
  auto_instrument=True, # Auto-instrument your app based on installed OI dependencies
  endpoint="http://0.0.0.0:6006/v1/traces"
)
```

## 図でまとめると

Arize AX, Arize Phoenix (SaaS)、Arize Phonenix (Self-host)は同時に使えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/b287b42c-7594-46e1-b3df-0d3929ff9305.png)

# LLM Tracing してみる

Langflow を起動してフローを実行するとログが転送されます。Langflow の Playground などを使ってフローを実行してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/888a63d4-124f-4ce9-8be4-d10cf1bac649.png)



Arize AX, Arize Phoenix (SaaS)、Arize Phonenix (Self-host) はほとんど同じ挙動ですが、Arize Phonenix (Self-host) で auto_instrument を True にした場合は、HTTP リクエストをトレースするため情報量が結構多いです。SaaS 版は LLM 関連のログが中心に残っている印象でした。

ここでは Self-host 版の画面を見てみます。ここまで述べた方法で作業していれば、[http://0.0.0.0:6006/projects](http://0.0.0.0:6006/projects)でアクセスできると思います。上記で指定した project_name が表示されているのでクリックして選択すると以下のような画面になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/1484864d-ce53-46d5-95ff-f06c65381b57.png)


auto_instrument を True にして取得しているので health_checkとかも取れてしまいます。Agent の動きに興味があるので、Spans の下の filter condition を以下のように設定してフィルタリングします。

- まずfilter conditionの右のところで、Root Spans だけではなく All を対象とするようにします。Root Spans は POST や GET といったリクエストを対象とするフィルタとなるので、All に設定してPOST の先に実行される Agent の処理まで拾えるようにします。
- filter condition のところに `name=="AgentExecutor"`といれると、Agent の挙動に絞り込めます。(span_kind == "AGENT"でも絞り込めます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/47ecdefd-a5ce-479c-a5d4-8e5af0e3aea0.png)

AgentExecutor をクリックすると、まずは Agent に対する入出力が見えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/048dce43-5dad-4d70-9d89-ac9807eec540.png)

オレンジ色のアイコンが付いた ChatBedrock は、エージェントに利用した Amazon Bedrock の動きを表しています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/ccaa543f-f25d-4aa8-ab48-274cc6f5e1a4.png)

上記はうまくフローが動かせたパターンですが、設定ミスで画像生成がうまくいかなかったパターンを見てみます。Agent の出力から「申し訳ありませんが、画像生成ツールの使用中にエラーが発生しました。セキュリティトークンの有効期限が切れているようです。」と言っているので、AWS のセキュリティトークンの設定にミスがあるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/fbdc872a-cc1d-4c94-a695-0ace60480b60.png)

念の為、Amazon Nova Canvas で画像生成を行う generate_image のツール (黄色いアイコン）の出力を見てみると、確かに`Error executing tool generate_image: Failed to generate image: An error occurred (ExpiredTokenException) when calling the InvokeModel operation: The security token included in the request is expired` といっています。なのでセキュリティトークンを更新することが解決策になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279199/8012f41d-39e1-46bd-a874-c53651f7c448.png)