> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# LangChain

> Weave を使用して、LangChain Python ライブラリ経由で行われるすべての Call をトラッキングしてログします

<a target="_blank" href="https://colab.research.google.com/github/wandb/examples/blob/master/weave/docs/quickstart_langchain.ipynb" aria-label="Google Colab で開く">
  <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Colab で開く" />
</a>

Weave は、[LangChain Python ライブラリ](https://github.com/langchain-ai/langchain)経由で行われる Call をトラッキングしてログします。

LLM を扱ううえで、デバッグは避けて通れない作業です。モデルの Call が失敗する、出力の形式が崩れる、ネストされたモデルの Call で処理の流れが分かりにくくなるなど、問題の原因を特定するのは簡単ではありません。LangChain アプリケーションは複数のステップと LLM Call の invocation で構成されることが多いため、チェーンやエージェントの内部動作を把握しておくことが重要です。

Weave は、[LangChain](https://docs.langchain.com/oss/python/langchain/overview) アプリケーションのトレースを自動的に取得します。これにより、アプリケーションのパフォーマンスを監視・分析できるため、LLM ワークフローのデバッグや最適化が容易になります。

このガイドは、LangChain アプリケーションを開発していて、Weave でトレース、評価、可観測性を導入したい開発者を対象としています。自動トレースの有効化、メタデータの付与、トレースの手動制御、そして評価に向けて LangChain チェーンを Weave モデルとしてラップする方法を順に説明します。

<h2 id="getting-started">
  はじめに
</h2>

まず、スクリプトの冒頭で `weave.init()` を呼び出します。`weave.init()` の引数にはプロジェクト名を指定します。Weave はこのプロジェクト名を使用してトレースを整理します。

```python lines {6} theme={"system"}
import weave
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI

# プロジェクト名を指定して Weave を初期化します
weave.init("langchain_demo")

llm = ChatOpenAI()
prompt = PromptTemplate.from_template("1 + {number} = ")

llm_chain = prompt | llm

output = llm_chain.invoke({"number": 2})

print(output)
```

<h2 id="track-call-metadata">
  Call のメタデータをトラッキングする
</h2>

カスタムメタデータを使用すると、Weights & Biases の UI でトレースをフィルターしたり分析したりできます。LangChain の Call からメタデータをトラッキングするには、[`weave.attributes`](/ja/products/wandb/weave/reference/python-sdk#function-attributes) コンテキストマネージャーを使用します。このコンテキストマネージャーでは、チェーンや単一のリクエストなど、特定のコードブロックを対象にカスタムメタデータを設定できます。

```python lines {6,13} theme={"system"}
import weave
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI

# プロジェクト名を指定して Weave を初期化します
weave.init("langchain_demo")

llm = ChatOpenAI()
prompt = PromptTemplate.from_template("1 + {number} = ")

llm_chain = prompt | llm

with weave.attributes({"my_awesome_attribute": "value"}):
    output = llm_chain.invoke()

print(output)
```

Weave は、LangChain の Call のトレースにメタデータを紐付けて自動的にトラッキングします。メタデータは Weave の Web インターフェースで確認できます。

[<img src="https://mintcdn.com/coreweave-dbfa0e8d/3Dv_sw2eg8feUJlx/products/wandb/weave/_media/langchain_attributes.png?fit=max&auto=format&n=3Dv_sw2eg8feUJlx&q=85&s=65bd57252e3eee63008c20e43e30ff0f" alt="LangChain のトレースのメタデータ属性を表示している Weights & Biases の UI" width="2908" height="588" data-path="products/wandb/weave/_media/langchain_attributes.png" />](https://forge.coreweave.com/wandb/parambharat/langchain_demo/weave/traces?cols=%7B%22attributes.weave.client_version%22%3Afalse%2C%22attributes.weave.os_name%22%3Afalse%2C%22attributes.weave.os_release%22%3Afalse%2C%22attributes.weave.os_version%22%3Afalse%2C%22attributes.weave.source%22%3Afalse%2C%22attributes.weave.sys_version%22%3Afalse%7D)

<h2 id="traces">
  トレース
</h2>

LLM アプリケーションのトレースを一元的なデータベースに保存しておくと、開発と本番運用の両方で役立ちます。蓄積したトレースは、アプリケーションのデバッグや改善に使用できるデータセットになります。

Weave は、LangChain アプリケーションのトレースを自動的に取得します。プロンプトテンプレート、チェーン、LLM Call、ツール、エージェントのステップなど、LangChain ライブラリを介して行われた Call をトラッキングしてログします。トレースは Weave の Web インターフェースで確認できます。

[<img src="https://mintcdn.com/coreweave-dbfa0e8d/3Dv_sw2eg8feUJlx/products/wandb/weave/_media/langchain_trace.png?fit=max&auto=format&n=3Dv_sw2eg8feUJlx&q=85&s=a67bc67f597bb2e2e48e94da54c511ab" alt="LangChain のトレースを表示している Weights & Biases の UI" width="1871" height="606" data-path="products/wandb/weave/_media/langchain_trace.png" />](https://forge.coreweave.com/wandb/parambharat/langchain_demo/weave/calls)

<h2 id="trace-calls-manually">
  Call を手動でトレースする
</h2>

自動トレースに加えて、`WeaveTracer` コールバックまたは `weave_tracing_enabled` コンテキストマネージャーを使用して、Call を手動でトレースすることもできます。これらの方法は、LangChain アプリケーションの個々の部分でリクエストコールバックを使用するのと似ています。アプリケーション全体ではなく、特定のチェーンや invocation だけをトレースしたい場合に使用してください。

以下のセクションでは、それぞれの方法について説明します。

注: Weave はデフォルトで LangChain の `Runnables` をトレースします。この機能は `weave.init()` を呼び出すと有効になります。この動作を無効にするには、`weave.init()` を呼び出す前に環境変数 `WEAVE_TRACE_LANGCHAIN` を `"false"` に設定します。これにより、アプリケーション内の特定のチェーン、さらには個々のリクエスト単位でトレース動作を制御できます。

<h3 id="use-weavetracer">
  `WeaveTracer` を使用する
</h3>

`WeaveTracer` コールバックを個々の LangChain コンポーネントに渡すと、特定のリクエストをトレースできます。

```python lines {11,13,15,22} theme={"system"}
import os

os.environ["WEAVE_TRACE_LANGCHAIN"] = "false" # <- グローバルトレースを明示的に無効にします。

from weave.integrations.langchain import WeaveTracer
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
import weave

# プロジェクト名を指定して Weave を初期化します
weave.init("langchain_demo")  # <-- 環境変数が明示的に `false` に設定されているため、ここではトレースは有効になりません

weave_tracer = WeaveTracer()

config = {"callbacks": [weave_tracer]}

llm = ChatOpenAI()
prompt = PromptTemplate.from_template("1 + {number} = ")

llm_chain = prompt | llm

output = llm_chain.invoke({"number": 2}, config=config) # <-- このチェーンの呼び出しでのみトレースが有効になります。

llm_chain.invoke({"number": 4})  # <-- langchain の Call はトレースされませんが、openai の Call は引き続きトレースされます
```

<h3 id="use-the-weave_tracing_enabled-context-manager">
  `weave_tracing_enabled` コンテキストマネージャーを使用する
</h3>

`weave_tracing_enabled` コンテキストマネージャーを使用して、特定のコードブロックでのみトレースを有効にすることもできます。

```python lines {11,18} theme={"system"}
import os

os.environ["WEAVE_TRACE_LANGCHAIN"] = "false" # <- グローバルなトレースを明示的に無効にします。

from weave.integrations.langchain import weave_tracing_enabled
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
import weave

# プロジェクト名を指定して Weave を初期化します
weave.init("langchain_demo")  # <-- 環境変数が明示的に `false` に設定されているため、ここではトレースは有効になりません

llm = ChatOpenAI()
prompt = PromptTemplate.from_template("1 + {number} = ")

llm_chain = prompt | llm

with weave_tracing_enabled():  # <-- このチェーンの呼び出しに限りトレースを有効にします。
    output = llm_chain.invoke({"number": 2})


llm_chain.invoke({"number": 4})  # <-- LangChain の Call はトレースされませんが、OpenAI の Call は引き続きトレースされます
```

<h2 id="configuration">
  設定
</h2>

`weave.init()` を呼び出すと、Weave は環境変数 `WEAVE_TRACE_LANGCHAIN` を `"true"` に設定し、トレースを有効にします。これにより、LangChain アプリケーションのトレースが Weave によって自動的に取得されます。この動作を無効にするには、この環境変数を `"false"` に設定してください。

<h2 id="relation-to-langchain-callbacks">
  LangChain のコールバックとの関係
</h2>

このセクションでは、Weave のトレースが LangChain のコールバックシステムとどのように連携するかを説明します。アプリケーションに最適なアプローチを選択する際の参考にしてください。

<h3 id="auto-logging">
  自動ログ
</h3>

`weave.init()` による自動ログは、LangChain アプリケーション内のすべてのコンポーネントにコンストラクターコールバックを渡すのと同様の効果があります。つまり Weave は、プロンプトテンプレート、チェーン、LLM Call、ツール、エージェントのステップなど、アプリケーション全体のあらゆるやり取りをグローバルにトラッキングします。

<h3 id="manual-logging">
  手動でのログ
</h3>

手動でログする方法 (`WeaveTracer` と `weave_tracing_enabled`) は、LangChain アプリケーションの個々の部分でリクエストコールバックを使用する方法に似ています。これらの方法を使用すると、アプリケーションのどの部分を Weave でトレースするかをより細かく制御できます。

* **コンストラクターコールバック:** チェーンまたはコンポーネント全体に適用され、すべてのやり取りを一貫してログします。
* **リクエストコールバック:** 特定のリクエストに適用され、個々の invocation を詳細にトレースします。

Weave を LangChain と統合すると、LLM アプリケーションのログとモニタリングが可能になり、デバッグやパフォーマンスのチューニングが容易になります。

詳細については、[LangChain のドキュメント](https://python.langchain.com/v0.2/docs/how_to/debugging/#tracing)を参照してください。

<h2 id="models-and-evaluations">
  モデルと評価
</h2>

さまざまなユースケースで LLM を整理・評価する作業は、プロンプト、モデルの設定、推論パラメーターなどのコンポーネントが増えるほど難しくなります。[`weave.Model`](/ja/products/wandb/weave/guides/core-types/models) を使用すると、システムプロンプトや使用するモデルといった実験の詳細を取得して整理できるため、反復処理の比較が容易になります。

以下のセクションでは、LangChain のチェーンを `weave.Model` としてラップし、評価する方法を説明します。

次の例では、LangChain のチェーンを `WeaveModel` でラップしています。

```python lines {10,12,16} theme={"system"}
import json
import asyncio

import weave

from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI

# プロジェクト名を指定して Weave を初期化します
weave.init("langchain_demo")

class ExtractFruitsModel(weave.Model):
    model_name: str
    prompt_template: str

    @weave.op()
    async def predict(self, sentence: str) -> dict:
        llm = ChatOpenAI(model=self.model_name, temperature=0.0)
        prompt = PromptTemplate.from_template(self.prompt_template)

        llm_chain = prompt | llm
        response = llm_chain.invoke({"sentence": sentence})
        result = response.content

        if result is None:
            raise ValueError("No response from model")
        parsed = json.loads(result)
        return parsed

model = ExtractFruitsModel(
    model_name="gpt-3.5-turbo-1106",
    prompt_template='Extract fields ("fruit": <str>, "color": <str>, "flavor": <str>) from the following text, as json: {sentence}',
)
sentence = "There are many fruits that were found on the recently discovered planet Goocrux. There are neoskizzles that grow there, which are purple and taste like candy."

prediction = asyncio.run(model.predict(sentence))

# Jupyter ノートブックで実行する場合は、次のようにします:
# prediction = await model.predict(sentence)

print(prediction)
```

このコードで作成したモデルは、Weights & Biases UI で可視化できます。

[<img src="https://mintcdn.com/coreweave-dbfa0e8d/3Dv_sw2eg8feUJlx/products/wandb/weave/_media/langchain_model.png?fit=max&auto=format&n=3Dv_sw2eg8feUJlx&q=85&s=6c7771162495ac79c1906f11230339c1" alt="LangChain チェーンを Weave モデルとしてラップした状態を表示している Weights & Biases UI" width="1868" height="835" data-path="products/wandb/weave/_media/langchain_model.png" />](https://forge.coreweave.com/wandb/parambharat/langchain_demo/weave/object-versions?filter=%7B%22baseObjectClass%22%3A%22Model%22%7D\&peekPath=%2Fparambharat%2Flangchain_demo%2Fobjects%2FExtractFruitsModel%2Fversions%2FBeoL6WuCH8wgjy6HfmuBMyKzArETg1oAFpYaXZSq1hw%3F%26)

Weave モデルは、`serve` や [`評価`](/ja/products/wandb/weave/guides/core-types/evaluations) と組み合わせて使用することもできます。

<h3 id="evaluations">
  評価
</h3>

評価を使用すると、モデルのパフォーマンスを測定できます。[`weave.Evaluation`](/ja/products/wandb/weave/guides/core-types/evaluations) クラスは、特定のタスクやデータセットでモデルがどの程度のパフォーマンスを発揮するかを取得します。これにより、異なるモデルやアプリケーションの反復処理を比較しやすくなります。次の例では、前述のモデルを評価する方法を示します。

```python lines theme={"system"}

from weave.scorers import MultiTaskBinaryClassificationF1

sentences = [
    "There are many fruits that were found on the recently discovered planet Goocrux. There are neoskizzles that grow there, which are purple and taste like candy.",
    "Pounits are a bright green color and are more savory than sweet.",
    "Finally, there are fruits called glowls, which have a very sour and bitter taste which is acidic and caustic, and a pale orange tinge to them.",
]
labels = [
    {"fruit": "neoskizzles", "color": "purple", "flavor": "candy"},
    {"fruit": "pounits", "color": "bright green", "flavor": "savory"},
    {"fruit": "glowls", "color": "pale orange", "flavor": "sour and bitter"},
]
examples = [
    {"id": "0", "sentence": sentences[0], "target": labels[0]},
    {"id": "1", "sentence": sentences[1], "target": labels[1]},
    {"id": "2", "sentence": sentences[2], "target": labels[2]},
]

@weave.op()
def fruit_name_score(target: dict, output: dict) -> dict:
    return {"correct": target["fruit"] == output["fruit"]}


evaluation = weave.Evaluation(
    dataset=examples,
    scorers=[
        MultiTaskBinaryClassificationF1(class_names=["fruit", "color", "flavor"]),
        fruit_name_score,
    ],
)
scores = asyncio.run(evaluation.evaluate(model)))
# Jupyter ノートブックで実行する場合は、次のようにします:
# scores = await evaluation.evaluate(model)

print(scores)
```

このコードを実行すると評価トレースが生成され、Weights & Biases UI で可視化できます。

[<img src="https://mintcdn.com/coreweave-dbfa0e8d/3Dv_sw2eg8feUJlx/products/wandb/weave/_media/langchain_eval.png?fit=max&auto=format&n=3Dv_sw2eg8feUJlx&q=85&s=d976896d54870ea8f57598334b36800f" alt="LangChain の評価トレースを表示している Weights & Biases UI" width="1868" height="835" data-path="products/wandb/weave/_media/langchain_eval.png" />](https://forge.coreweave.com/wandb/parambharat/langchain_demo/weave/calls?filter=%7B%22traceRootsOnly%22%3Atrue%7D\&peekPath=%2Fparambharat%2Flangchain_demo%2Fcalls%2F44c3f26c-d9d3-423e-b434-651ea5174be3)

<h2 id="known-issues">
  既知の問題
</h2>

**非同期 Call のトレース**: LangChain の `AsyncCallbackManager` の実装にバグがあるため、非同期 Call が正しい順序でトレースされません。Weave はこの問題を修正する [PR](https://github.com/langchain-ai/langchain/pull/23909) を提出済みです。この問題により、LangChain の `Runnables` で `ainvoke`、`astream`、`abatch` メソッドを使用すると、トレース内の Call の順序が正しく表示されない場合があります。
