LangChain
LangChain
LLM 애플리케이션을 만들 때 LangChain을 쓰고 있다면, init() 한 번으로 추적·평가를 시작할 수 있어요. confident-trace는 Python과 TypeScript용 OpenTelemetry 네이티브 추적 SDK로, LangChain 애플리케이션을 자동으로 추적·평가합니다. 체인 코드는 그대로 두면 돼요.
출처: 문서
본문
개요
LangChain은 LLM 애플리케이션을 만드는 프레임워크입니다. Confident AI는 Python·TypeScript용 OpenTelemetry 네이티브 추적 SDK인 confident-trace로 LangChain 애플리케이션을 자동 추적·평가해요 — init()을 한 번 호출하면 체인 코드는 그대로 유지됩니다.
이 통합은 LangChain 애플리케이션에서 다음 스팬을 포착합니다.
- 체인·runnable 스팬 — 체인 하나와 그 안의 각 중간 runnable마다 스팬 하나, 입출력 포함
- LLM 스팬 — 모델 이름, 토큰 사용량, 완료 사유, (모델이 한 도구 호출 포함) 입출력 메시지
- 도구 스팬 — 도구 이름, 입력 매개변수, 출력이 그것을 실행한 체인 아래에 중첩
- 리트리버 스팬 — 쿼리 입력과 검색된 문서 텍스트
LangChain과 LangGraph는
confident-trace에서 하나의 콜백 브리지를 공유하므로, 그래프 호출도 같은 통합으로 추적됩니다 — 추가 핸들러가 필요 없어요.thread_id처리와 체크포인트 같은 그래프별 세부 사항은 LangGraph 페이지를 참고하세요.
| Runtime | Requirements | Setup |
|---|---|---|
| Python | Python 3.10+, LangChain 1.x | Call init() before running the chain |
| TypeScript | Node.js 22+, @langchain/core >=1.2.9 <2 |
Call init() and launch your entry point with the preload |
자동 계측
의존성 설치
confident-trace를 LangChain과 함께 설치하는 명령을 실행하세요.
Python
pip install confident-trace 'langchain>=1,<2' 'langchain-openai>=1,<2'
TypeScript
tsx는 TypeScript 소스를 직접 실행할 때만 필요해요.
npm install confident-trace '@langchain/core@>=1.2.9 <2' @langchain/openai@1
npm install -D tsx
yarn add confident-trace '@langchain/core@>=1.2.9 <2' @langchain/openai@1
yarn add -D tsx
API 키 설정
Confident AI Project API key를 받아 모델 프로바이더 키와 함께 환경 변수로 설정하세요.
export CONFIDENT_API_KEY="<your-confident-project-key>"
export OPENAI_API_KEY="<your-openai-key>"
EU 리전이거나 자체 호스팅 배포라면, 트레이스가 우리 US 서버로 가지 않도록
CONFIDENT_OTEL_ENDPOINT도 설정하세요 —init()구성을 참고하세요.
LangChain 계측
체인을 실행하기 전에 init()을 한 번 호출하세요. LangChain을 자동으로 감지해 콜백 핸들러를 붙여 줘요 — invoke에 전달할 핸들러도, 설치할 트레이싱 extra도 없습니다.
Python
from confident_trace import init, shutdown
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
init()
prompt = ChatPromptTemplate.from_template("Explain {topic} in one sentence.")
chain = prompt | ChatOpenAI(model="gpt-4.1-mini") | StrOutputParser()
try:
print(chain.invoke({"topic": "OpenTelemetry"}))
finally:
shutdown()
TypeScript
import { init } from "confident-trace";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { ChatOpenAI } from "@langchain/openai";
const runtime = init();
const prompt = ChatPromptTemplate.fromTemplate("Explain {topic} in one sentence.");
const chain = prompt
.pipe(new ChatOpenAI({ model: "gpt-4.1-mini" }))
.pipe(new StringOutputParser());
try {
console.log(await chain.invoke({ topic: "OpenTelemetry" }));
} finally {
await runtime.shutdown();
}
TypeScript에는 한 가지가 더 필요합니다. Node가 @langchain/core를 로드할 때 SDK가 훅할 수 있도록 엔트리포인트를 confident-trace/register preload로 실행하세요. init()은 export를, preload는 계측을 처리합니다 — 둘 다 필요해요.
preload 없이
init()을 호출하면 설정 경고가 나오고 스팬이 없어요. 반대로 preload만 있고init()이 없으면 스팬은 만들어지지만 아무것도 내보내지지 않습니다.
장기 실행 서버에서는 시작 시
init()을 한 번, 정상 종료 시 활성 체인 작업이 끝난 뒤shutdown()을 한 번 호출하세요 — 요청마다 하지 마세요. 한 번 초기화를 참고하세요.
LangChain 실행
스크립트를 실행해 트레이스를 Confident AI로 보내세요.
Python
python main.py
TypeScript
# Running TypeScript source directly
node --import tsx --import confident-trace/register src/index.ts
# Running compiled JavaScript
node --import confident-trace/register dist/index.js
이걸 평소 시작 명령으로 만들려면 package.json scripts에 추가하세요.
{
"scripts": {
"start": "node --import confident-trace/register dist/index.js",
"dev": "node --import tsx --import confident-trace/register src/index.ts"
}
}
완료 ✅. Confident AI 프로젝트에서 Observatory를 열어 트레이스와 체인·모델·파서 스팬을 확인하세요.
트레이스가 안 보이면 99.99% 프로그램이 스팬을 보낼 기회가 생기기 전에 종료됐기 때문이에요. 종료 전에 반드시
shutdown()(장기 실행 프로세스에선flush())을 호출하세요 — 트러블슈팅 페이지를 참고하세요.
무엇이 포착되나
통합은 LangChain이 콜백으로 보고하는 계층을 그대로 반영합니다.
- 체인·runnable — 체인 하나와 그 안의 각 중간 runnable마다 스팬 하나. 이것들은 일반 스팬이며, 체인 이름만으로 에이전트로 표시되진 않아요. (에이전트 타입 루트를 원하면 호출을 에이전트 타입
span으로 감싸세요 — 커스텀 애플리케이션 스팬 참고) - 모델 호출 — 모델 정보, 토큰 사용량, 완료 사유, 정규화된 입출력 메시지를 담은 LLM 스팬
- 도구 실행 — 프레임워크 부모를 따르는 도구 스팬. 모델의 도구 요청은 모델 스팬의 출력에 나타나요.
- 리트리버 — 검색된 문서 텍스트를 담은 리트리버 스팬
체인 상태, 도구 값, 문서 텍스트는 콘텐츠 정책을 따릅니다. 크기 제한은 기본적으로 꺼져 있지만, export 전에 제한을 구성하거나 콘텐츠를 삭제할 수 있어요.
Python
지원되는 LangChain 작업 안에서는 OpenTelemetry 컨텍스트가 활성이므로, 도구 안에서 만든 커스텀 스팬이 자동으로 그 아래에 중첩됩니다.
TypeScript
콜백은 LangChain 계층은 보존하지만 도구 코드를 감싸지는 않아요. 도구 안에서 만든 무관한 HTTP·DB 스팬은, 그 작업을 자체
span으로 감싸지 않는 한 그 아래에 부모로 연결되지 않습니다.
스트리밍
스트리밍도 invoke와 같은 방식으로 추적됩니다. 모델 스팬은 스트림이 끝날 때 완료돼요. 이 조각들은 빠른 시작의 try 블록 안 chain.invoke 호출을 대체합니다.
Python
stream = chain.stream({"topic": "OpenTelemetry"})
try:
for chunk in stream:
print(chunk, end="", flush=True)
finally:
stream.close()
ainvoke, astream, 배치 작업, astream_events v2도 지원됩니다.
TypeScript
const stream = await chain.stream({ topic: "OpenTelemetry" });
for await (const chunk of stream) process.stdout.write(chunk);
shutdown()전에 스트림을 소비하거나 닫으세요. 버려진 스트림은 스팬을 열어 둔 채 트레이스가 불완전해져요. flush와 shutdown을 참고하세요.
트레이스 스팬 속성 설정
호출이 시작되기 전에 아는 속성을 추가하려면 트레이스 컨텍스트를 사용하세요. 추가 스팬은 만들지 않아요. chain.invoke()가 시작한 트레이스가 태그, 메타데이터, 사용자 ID, 고객 ID를 상속받습니다.
Python
from confident_trace import init, trace_context
from langchain_openai import ChatOpenAI
init()
model = ChatOpenAI(model="gpt-4.1-mini")
chain = model
with trace_context(
tags=["support"],
metadata={"release": "2026-09"},
user_id="user-42",
customer_id="customer-7",
):
result = chain.invoke("Explain OpenTelemetry in one sentence.")
TypeScript
import { init, traceContext } from "confident-trace";
import { ChatOpenAI } from "@langchain/openai";
init();
const chain = new ChatOpenAI({ model: "gpt-4.1-mini" });
const result = await traceContext(
{
tags: ["support"],
metadata: { release: "2026-09" },
userId: "user-42",
customerId: "customer-7",
},
() => chain.invoke("Explain OpenTelemetry in one sentence."),
);
각 ID와 함께 선택적 표시 이름을 설정하려면 사용자와 고객을, 지원되는 모든 트레이스 속성과 갱신 동작은 트레이스 컨텍스트를 참고하세요.
다중 턴 계측
LangChain 엔트리포인트 호출 하나가 이미 하나의 대화 턴일 때는 turn()이 필요 없어요 — 통합이 그 턴의 트레이스를 자동으로 만들어 주거든요. 경계를 직접 정의하고 싶을 때, 예를 들어 두 번의 연속 LangChain 호출을 하나의 턴으로 묶고 싶을 때 turn()을 사용하세요. 이후 턴에서 같은 스레드 ID를 재사용해 하나의 대화로 묶으면 돼요.
Python
from confident_trace import init, turn
init()
with turn("support-turn", thread_id="chat-42"):
context = chain.invoke("Find the relevant account details.")
answer = chain.invoke(f"Answer the user using this context: {context.content}")
TypeScript
import { init, turn } from "confident-trace";
init();
const answer = await turn({ name: "support-turn", threadId: "chat-42" }, async () => {
const context = await chain.invoke("Find the relevant account details.");
return chain.invoke(`Answer the user using this context: ${context.content}`);
});
스레드 입출력, 턴 ID, 사용자 ID는 스레드를 참고하세요.
트러블슈팅
Python
- 트레이스 없음: 체인이 실행되기 전에
init()이 실행되고, 프로세스가shutdown()에 도달해 버퍼링된 스팬이 플러시되는지 확인하세요. - 불완전한 스트림:
shutdown()전에 스트림을 소비하거나 닫으세요.
TypeScript
- 트레이스 없음: 체인 실행 전에
init()이 실행되고, 시작 명령에--import confident-trace/register가 포함되며,shutdown()에 도달해 버퍼링된 스팬이 플러시되는지 확인하세요.runtime.getInstrumentationStatus()가 LangChain 훅이 붙었는지 알려 줘요. - 불완전한 스트림:
shutdown()전에 스트림을 소비하거나 닫으세요. - 예상치 못한 부모 관계: 콜백은 애플리케이션 코드를 감싸지 않아요. 공통 부모가 필요한 무관한 작업은 트레이스 스팬 속성 설정처럼 명시적
span으로 감싸세요.
일반 설정 문제는 트러블슈팅을 참고하세요.
LangChain 계측 비활성화
특정 통합만 활성화하려면 init()에 통합 식별자 목록을 전달하세요. LangChain의 식별자는 Python·TypeScript 모두 "langchain"이고, 이를 빼면 이 통합이 비활성화돼요. 빈 목록은 모든 자동 계측을 비활성화합니다.
Python
from confident_trace import init
init(instrumentations=())
# Use ("langchain",) to opt in; omit "langchain" to disable it.
TypeScript
import { init } from "confident-trace";
init({ instrumentations: [] });
// Use ["langchain"] to opt in; omit "langchain" to disable it.
이렇게 하면 Confident AI의 자동 계측이 꺼지고, 초기화 이후의 호출은 이 통합으로 계측되지 않아요.
다음 단계
Online Evals
트레이스와 스팬이 Confident AI로 수집되는 실시간으로 평가를 돌려 프로덕션 AI 품질을 모니터링하세요.
LangGraph 통합
LangGraph로 에이전트를 만들고 있나요? 같은 통합이 그래프, 노드, 체크포인트된 대화를 추적합니다.
더 알아보기
- LangGraph — 그래프·노드·체크포인트 대화 추적
- OpenAI — 공식 OpenAI 클라이언트 추적
- Online Evals — 실시간 트레이스·스팬 평가