Langfuseのミートアップに参加したので、Langfuseを試してみた

# はじめに
つい先日、Langfuseをほぼ知らない状態で、[Langfuse Night #1](https://connpass.com/event/340099/)に、先輩社員の方に誘われて行きました。
そこでの登壇やその後の懇親会での話を聞く感じ、現在携わっているAIアプリにもLangfuseが有用そうだったので、Langfuseを試してみました。

# Langfuseとは？
Langfuse は、LLMアプリケーションの管理を支援するオープンソースのツールで、プロンプトのバージョン管理、コスト分析、LLM の出力評価などを一元的に管理できます。
似たようなツールにLangsmithというのもありますが、こちらはフルマネージドで、今開発してるアプリの制約的にセルフホスティングの必要があるので、今のアプリにはLangfuseの方が合いそうだと思いました。

https://langfuse.com/



# 環境
AIアプリとLangfuse、どちらもローカルで動かします。
AIアプリの方はフロントとバックを両方Next.jsで構築しています。
AIアプリは、OpenAIを使用しています。

## Langfuseの環境構築
dockerが楽そうだったので、dockerで構築
[公式サイト](https://langfuse.com/self-hosting/local)の手順に沿って構築しました。
```
git clone https://github.com/langfuse/langfuse.git
cd langfuse
docker compose up
```
port3000は既に使用済みだったので、`docker-compose.yml`のport部分を以下のように修正
```yml
    ports:
      - "3001:3000"
    environment:
      <<: *langfuse-worker-env
      NEXTAUTH_URL: http://localhost:3001
```
## Langfuseのセットアップ
`http://localhost:3001`にアクセスし、新規アカウントを作成（ローカルに作成されるだけなので適当でOK）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/bd2130e4-f6e0-58a7-e464-1fe121daf6ca.png)

New Organizationをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/6a63392c-fd6b-f776-e13a-7a2357038d66.png)

Organizationを入力してCreateをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/1d8a7293-494b-5b62-4bae-dddb8c7699ea.png)

Nextを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/7e417578-1060-45dc-2304-ec4e95dd0d06.png)

プロジェクト名を入力してCreate
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/3e601025-d00b-ed51-e491-7576b4971ea5.png)

この画面になったら左のAPI Keysを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/942af547-7c60-5759-515f-94a011e93bb0.png)

Crerate new API keysを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/d312ebf3-f447-042c-c9bd-cd70725c0413.png)

APIキーを取得　パブリックキーとシークレットキーを控えておく（シークレットキーはこれを閉じると見えなくなる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/45d71444-630d-3cc6-db53-cc686235317a.png)
(キーを隠す必要はないのですが一応隠しています。)

これでlangfuse側の設定は完了

# アプリ側の設定
前述した通り、アプリはバックもフロントもNext.jsで構築しています。
TSのOpenAI SDKをラップしようと思うので、[OpenAI Integration (JS/TS)](https://langfuse.com/docs/integrations/openai/js/examples)を参考にします。
## インストール
```
npm i langfuse
```
でlangfuseをインストール

## 環境変数
一応APIキーなどは環境変数に出しておきます。ここには、先程控えておいたシークレットキーとパブリックキーを設定します。
```
LANGFUSE_HOST=http://localhost:3001/
LANGFUSE_PUBLIC_KEY=<先ほど控えておいたパブリックキー>
LANGFUSE_SECRET_KEY=<先ほど控えておいたシークレットキー>
```

## OpenAI SDKをラップする
```typescript
import { observeOpenAI } from 'langfuse';
```

```typescript
const openAI = new OpenAI(parameter)
```
で作成していたOpenAIインスタンスを、以下のようにラップします。
```typescript
const openAI =  observeOpenAI(new OpenAI(parameter), {
    clientInitParams: {
      publicKey: process.env.LANGFUSE_PUBLIC_KEY,
      secretKey: process.env.LANGFUSE_SECRET_KEY,
      baseUrl: process.env.LANGFUSE_HOST,
    },
  });
```
これでAIアプリ側の設定も完了です。めっちゃ簡単。

## Langfuseを動かしてみる
大筋とは関係ないのですが、ここで少しハマりました。LangfuseもAIアプリもNextAuthを利用しているのですが、同じブラウザでLangfuseとアプリを開くとNextAuth関連のエラーが出る(勝手にログアウトされる)ので、別々のブラウザで開くようにしました。

AIアプリ内で、AIにプロンプトを投げると以下のようなプロンプトのトレースができるようになりました。(情報が情報なだけにモザイクです... すみません...)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/caf92275-9d61-c754-45ed-45bbd1044fb9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940611/6e3ce441-20e2-9905-c996-e966aaa6dba8.png)

# 今後の展望
現在、回答精度向上の話が出てきているので、その管理にLangfuseが使えたらいいなと思っています。
Ragasの結果とかもLangfuseで管理できたら良さそう。

まだローカルでの動作段階なので簡単に構築できましたが、これをデプロイして動かすとなると結構面倒そうだなと思いました。（特にv3になってから構築が面倒になったとか...）