> ## 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로 구성되는 경우가 많으므로 체인과 에이전트가 내부적으로 어떻게 동작하는지 파악해 두면 도움이 됩니다.

Weave는 [LangChain](https://docs.langchain.com/oss/python/langchain/overview) 애플리케이션의 트레이스를 자동으로 캡처합니다. 이를 통해 애플리케이션의 성능을 모니터링하고 분석할 수 있어 LLM 워크플로를 더 쉽게 디버깅하고 최적화할 수 있습니다.

이 가이드는 LangChain 애플리케이션을 구축하면서 Weave로 트레이싱, 평가, 관측성을 추가하려는 개발자를 대상으로 합니다. 자동 트레이싱 활성화, 메타데이터 첨부, 트레이싱 수동 제어, 그리고 평가를 위해 LangChain 체인을 Weave Model로 래핑하는 방법을 차례로 안내합니다.

<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`](/ko/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 웹 인터페이스에서 확인할 수 있습니다.

[<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 애플리케이션의 트레이스를 자동으로 캡처합니다. Weave는 LangChain 라이브러리를 통해 이루어진 Call을 프롬프트 템플릿, 체인, LLM Call, 도구, 에이전트 step까지 포함하여 추적하고 로깅합니다. 트레이스는 Weave 웹 인터페이스에서 확인할 수 있습니다.

[<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` callback이나 `weave_tracing_enabled` 컨텍스트 관리자를 사용해 Call을 수동으로 트레이스할 수 있습니다. 이 방법은 LangChain 애플리케이션의 개별 부분에 요청 callback을 적용하는 방식과 비슷합니다. 애플리케이션 전체가 아닌 특정 체인이나 호출만 트레이스하려면 이 방법을 사용하세요.

다음 섹션에서 각 방법을 설명합니다.

참고: Weave는 기본적으로 LangChain `Runnables`를 트레이스하며, 이 기능은 `weave.init()`을 호출하면 활성화됩니다. `weave.init()`을 호출하기 전에 환경 변수 `WEAVE_TRACE_LANGCHAIN`을 `"false"`로 설정하면 이 동작을 비활성화할 수 있습니다. 이렇게 하면 애플리케이션의 특정 체인은 물론 개별 요청 단위로도 트레이싱 동작을 제어할 수 있습니다.

<h3 id="use-weavetracer">
  `WeaveTracer` 사용하기
</h3>

`WeaveTracer` callback을 개별 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 호출은 트레이싱되지 않지만, OpenAI 호출은 여전히 트레이싱됩니다
```

<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"`로 설정하여 트레이싱을 활성화합니다. 따라서 Weave가 LangChain 애플리케이션의 트레이스를 자동으로 캡처합니다. 이 동작을 비활성화하려면 해당 환경 변수를 `"false"`로 설정하세요.

<h2 id="relation-to-langchain-callbacks">
  LangChain callback과의 관계
</h2>

이 섹션에서는 Weave의 트레이싱이 LangChain의 callback 시스템과 어떻게 통합되는지 설명합니다. 이를 참고하여 애플리케이션에 가장 적합한 방식을 선택하세요.

<h3 id="auto-logging">
  자동 로깅
</h3>

`weave.init()`이 제공하는 자동 로깅은 LangChain 애플리케이션의 모든 컴포넌트에 생성자 callback을 전달하는 것과 비슷합니다. 즉, Weave는 프롬프트 템플릿, 체인, LLM Call, 도구, 에이전트 step을 비롯해 애플리케이션 전체의 모든 상호작용을 전역적으로 추적합니다.

<h3 id="manual-logging">
  수동 로깅
</h3>

수동 로깅 방법(`WeaveTracer` 및 `weave_tracing_enabled`)은 LangChain 애플리케이션의 개별 부분에 요청 callback을 사용하는 방식과 비슷합니다. 이 방법을 사용하면 애플리케이션의 어느 부분을 Weave로 트레이스할지 더 세밀하게 제어할 수 있습니다.

* **생성자 callback:** 체인 또는 컴포넌트 전체에 적용되며 모든 상호 작용을 일관되게 로깅합니다.
* **요청 callback:** 특정 요청에 적용되며 해당 호출에 대한 상세 트레이싱을 제공합니다.

Weave를 LangChain과 통합하면 LLM 애플리케이션을 로깅하고 모니터링할 수 있어 디버깅과 성능 튜닝이 쉬워집니다.

자세한 내용은 [LangChain 문서](https://python.langchain.com/v0.2/docs/how_to/debugging/#tracing)를 참조하세요.

<h2 id="models-and-evaluations">
  모델 및 평가
</h2>

다양한 사용 사례에 걸쳐 LLM을 체계적으로 관리하고 평가하는 일은 프롬프트, 모델 설정, 추론 매개변수 같은 컴포넌트가 늘어날수록 어려워집니다. [`weave.Model`](/ko/products/wandb/weave/guides/core-types/models)을 사용하면 system 프롬프트나 사용 중인 모델 같은 실험 세부 정보를 캡처하고 정리할 수 있어 반복 버전을 더 쉽게 비교할 수 있습니다.

다음 섹션에서는 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 Notebook에서는 다음을 실행하세요:
# 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="Weave Model로 래핑된 LangChain 체인을 보여주는 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 Model은 `serve` 및 [`평가`](/ko/products/wandb/weave/guides/core-types/evaluations)와 함께 사용할 수도 있습니다.

<h3 id="evaluations">
  평가
</h3>

평가를 사용하면 모델의 성능을 측정할 수 있습니다. [`weave.Evaluation`](/ko/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 Notebook을 사용하는 경우 다음을 실행하세요:
# 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의 순서가 실제와 다를 수 있습니다.
