LangSmithを動かす

## [LangSmith](https://www.langchain.com/langsmith)とは
LLMアプリの開発プラットフォームです。デバッグ、詳細なログ、トークン数とかを見ることができます。

![スクリーンショット 2024-09-23 111813.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289684/e0a4ccef-862b-7b96-d620-95d6e8165146.png)


こんなデータを送ってやると↓
### Input
```
*HUMAN*
LangSmithのログテストです。東京の天気はどうですか？
```

こんな結果↓を返すAIに対して
### Output
```
*AI*
申し訳ありませんが、私はリアルタイムの情報にアクセスできません。そのため、東京の現在の天気についてはお答えできません。最新の天気予報については、信頼できる天気予報サイトをご確認ください。
```

こういう↓詳細な生データ（Input）と
### Raw Input
```yml
messages:
  - lc: 1
    type: constructor
    id:
      - langchain
      - schema
      - messages
      - HumanMessage
    kwargs:
      content: LangSmithのログテストです。東京の天気はどうですか？
      type: human
```

Outputもこんな感じ↓で表示してくれる（長い）
### Raw Output
```yml
llm_output:
  prompt_feedback:
    block_reason: 0
    safety_ratings: []
run: null
type: LLMResult
generations:
  - text: |
      申し訳ありませんが、私はリアルタイムの情報にアクセスできません。そのため、東京の現在の天気についてはお答えできません。最新の天気予報については、信頼できる天気予報サイトをご確認ください。 
    generation_info:
      finish_reason: STOP
      safety_ratings:
        - category: HARM_CATEGORY_SEXUALLY_EXPLICIT
          probability: NEGLIGIBLE
          blocked: false
        - category: HARM_CATEGORY_HATE_SPEECH
          probability: NEGLIGIBLE
          blocked: false
        - category: HARM_CATEGORY_HARASSMENT
          probability: NEGLIGIBLE
          blocked: false
        - category: HARM_CATEGORY_DANGEROUS_CONTENT
          probability: NEGLIGIBLE
          blocked: false
    type: ChatGeneration
    message:
      lc: 1
      type: constructor
      id:
        - langchain
        - schema
        - messages
        - AIMessage
      kwargs:
        content: |
          申し訳ありませんが、私はリアルタイムの情報にアクセスできません。そのため、東京の現在の天気についてはお答えできません。最新の天気予報については、信頼できる天気予報サイトをご確認ください。 
        response_metadata:
          prompt_feedback:
            block_reason: 0
            safety_ratings: []
          finish_reason: STOP
          safety_ratings:
            - category: HARM_CATEGORY_SEXUALLY_EXPLICIT
              probability: NEGLIGIBLE
              blocked: false
            - category: HARM_CATEGORY_HATE_SPEECH
              probability: NEGLIGIBLE
              blocked: false
            - category: HARM_CATEGORY_HARASSMENT
              probability: NEGLIGIBLE
              blocked: false
            - category: HARM_CATEGORY_DANGEROUS_CONTENT
              probability: NEGLIGIBLE
              blocked: false
        type: ai
        id: run-12345678-abcd-4567-efgh-0123456789ab-0
        usage_metadata:
          input_tokens: 14
          output_tokens: 36
          total_tokens: 50
        tool_calls: []
        invalid_tool_calls: []
```

とても便利なツールです
ちなみに上記はGemini1.5 Flashの出力結果です。
PromptTemplateやLLM、OutputParser、Tool、Agent等、Chainを使って開発する時にはとても便利なんですが、細かいところは置いておいて、便利です（語彙力）

## LangSmithのキーを取得
まずは[LangSmithのWEBサイト](https://www.langchain.com/langsmith)でキーを取得して下さい。
[sign up]を押すだけですね。

## LangChainTracerを使わない方法（環境変数を使う方法）
### Pythonでos.environに書きこんで使用
- Google Colaboのシークレット機能を使っていますが、要するに環境変数を使っているだけですので、自由に書き換えて使用してください
- ただこの方法だと私は動作しなくなったので、動作しない方は後ほど紹介する「LangChainTracerを使う方法」をお試しください（そちらでは私は動作した）
```python
import os
from uuid import uuid4

# 環境変数の準備
unique_id = uuid4().hex[0:8]
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = f"Tracing Walkthrough - {unique_id}"
os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com"
os.environ["LANGCHAIN_API_KEY"] = userdata.get("LANGCHAIN_API_KEY")
```

### shellで環境変数に書きこんで使用
- こちらも良くある方法ですが、動作しなかった方は「LangChainTracerを使う方法」をお試し下さい
```shell
export LANGCHAIN_TRACING_V2="true"
export LANGCHAIN_API_KEY="your_api_key_here"
```
- ちなみに LANGCHAIN_TRACING に "true" を設定するとエラーが発生します


## LangChainTracerを使う方法

### LangSmithのパッケージを入れる
```shell
pip install langsmith
```
### あとはPythonで呼ぶだけ
```python
from langchain.callbacks.manager import CallbackManager
from langchain.callbacks import LangChainTracer

import langchain
langchain.debug = True

tracer = LangChainTracer(project_name=os.environ["LANGCHAIN_PROJECT"])
callback_manager = CallbackManager([tracer])

llm = ChatGoogleGenerativeAI(
    model="models/gemini-1.5-flash",
    callback_manager=callback_manager
)

messages = [
    ("human", "LangSmithのログテストです。東京の天気はどうですか？")
]
output = llm.invoke(messages)

print(output)
```
- LangChainTracerのコンストラクタにあるproject_nameでプロジェクト名を指定します。環境変数から取得するように記述していますが、任意の名前を使用して下さい。指定しないと"default"という名称のprojectにデータが保存されます
- modelは任意のモデルを利用し、KEYの設定を適切に行ってください

## 感想
- 備忘録です
- 動いていたはずのものが動かなかったりしてるなぁと思ったので書いておきました