1. 학습 주제
LangSmith를 사용해 AI Workflow 실행 과정을 추적하고, 실패 원인을 확인하며, 수정 전후 결과를 Dataset과 Experiment로 비교하는 흐름을 학습했다.
핵심 내용은 다음과 같다.
- LangSmith 환경 설정 확인
- @traceable을 사용한 실행 추적
- Workflow 실행 Trace 기록
- 실패 Workflow 추적
- baseline 버전과 fixed 버전 비교
- Dataset 생성
- Evaluator 작성
- Experiment 실행과 비교
2. LangSmith란?
LangSmith는 LangChain, LangGraph 기반 애플리케이션의 실행 과정을 관찰하고 평가할 수 있게 도와주는 도구이다.
AI Workflow는 내부에서 여러 단계가 실행된다.
Planner
-> Executor
-> Task 실행
-> Validator
-> 결과 반환
이 흐름이 실패했을 때 단순히 “답이 이상하다”로는 원인을 찾기 어렵다.
LangSmith를 사용하면 각 단계가 어떤 입력을 받고, 어떤 출력을 만들었는지 Trace로 확인할 수 있다.
3. 환경 변수 설정
LangSmith에 Trace를 업로드하려면 환경 변수가 필요하다.
LANGSMITH_API_KEY
LANGSMITH_TRACING
LANGSMITH_PROJECT
설정 확인 함수에서는 누락된 값과 잘못된 값을 검사했다.
LANGSMITH_REQUIRED = (
"LANGSMITH_API_KEY",
"LANGSMITH_TRACING",
"LANGSMITH_PROJECT",
)
LANGSMITH_TRACING은 true 계열 값이어야 한다.
if tracing and tracing not in {"true", "1", "yes", "on"}:
errors.append("LANGSMITH_TRACING은 true여야 합니다.")
API Key는 그대로 출력하지 않고 일부만 마스킹해서 확인했다.
Key를 로그에 그대로 노출하지 않는 습관도 중요하다.
4. Trace
Trace는 실행 기록이다.
어떤 함수가 어떤 입력으로 실행되었고, 어떤 결과나 에러를 냈는지 남긴다.
이번 Workflow에서는 각 Task 함수를 @traceable로 감쌌다.
@traceable(name="task-destination", run_type="tool")
def traced_destination(request, context):
execute_destination(request, context)
return {
"destinations": [
place.model_dump() for place in context["destinations"]
]
}
이렇게 하면 LangSmith에서 task-destination, task-budget, task-compose 같은 단계를 각각 확인할 수 있다.
5. Workflow Trace 구조
Workflow 전체도 @traceable로 감싸서 하나의 Chain 실행으로 기록했다.
@traceable(name="d-travel-workflow", run_type="chain")
def run_workflow(inputs: dict, version: PlanVersion = "fixed") -> dict:
...
실행 흐름은 다음과 같다.
run_workflow
-> build_workflow
-> planner
-> executor
-> task-requirements
-> task-weather
-> task-destination
-> task-budget
-> task-compose
-> validator
Trace를 보면 전체 흐름뿐 아니라 내부 Task별 실행 결과까지 볼 수 있다.
그래서 실패했을 때 어느 Task에서 문제가 생겼는지 확인하기 쉽다.
6. baseline과 fixed
이번 실습에서는 Workflow 버전을 나누어 실행했다.
PlanVersion = Literal["baseline", "fixed", "llm", "runtime_error"]
각 버전의 의미는 다음과 같다.
| 버전 | 의미 |
| baseline | 수정 전 Plan |
| fixed | 수정 후 Plan |
| llm | 실제 LLM이 생성한 Plan |
| runtime_error | 오류 재현용 Plan |
baseline은 destination Task가 빠진 Plan이었다.
requirements
-> weather
-> budget
-> compose
장소 후보를 검색하지 않고 예산 계산과 일정 작성을 진행하므로 검증 실패가 발생할 수 있다.
fixed는 장소 검색 Task까지 포함한다.
requirements
-> weather
-> destination
-> budget
-> compose
즉, 수정 전후의 차이를 LangSmith에 기록하고 비교할 수 있게 구성했다.
7. 실패 Trace 확인
실패를 일부러 재현하는 코드도 있었다.
version="runtime_error"
runtime_error 버전은 compose Task가 빠져 있어 최종 draft가 생성되지 않는다.
if draft is None:
raise ValueError("실행 결과에 Draft가 없습니다. compose Task를 확인하세요.")
이런 실패를 LangSmith Trace로 남기면 어느 단계까지 실행됐고, 어떤 Task가 빠져서 예외가 발생했는지 확인할 수 있다.
실패 디버깅에서 중요한 점은 다음과 같다.
실패 결과만 보지 말고
실행 경로와 중간 결과를 같이 확인한다.
8. Validator 보완
Validator는 Workflow 결과가 요구사항을 만족하는지 판단한다.
이번에는 예산 조건 검증도 추가되었다.
if budget_options and not any(
bool(option["within_budget"]) for option in budget_options
):
cheapest = min(int(option["total"]) for option in budget_options)
report = ValidationReport(
passed=False,
failed_conditions=[
f"최저 예상 비용 {cheapest:,}원이 예산 {state['request'].budget:,}원을 초과합니다."
],
)
단순히 Task가 실행됐는지만 보는 것이 아니라, 실제 결과가 사용자의 예산 조건을 만족하는지도 확인한다.
9. Dataset
Dataset은 평가에 사용할 입력과 기대 결과 모음이다.
EVALUATION_CASES = [
{
"inputs": {
"goal": "비 오는 날 아이와 갈 송파 하루 일정을 만들어줘.",
"weather": "rain",
"people": 3,
"budget": 200_000,
"children": True,
},
"outputs": {"expected_pass": True},
}
]
Dataset을 만들면 같은 테스트 케이스로 여러 버전의 Workflow를 반복 평가할 수 있다.
workflow-v1 Dataset
-> baseline Experiment
-> fixed Experiment
10. Evaluator
Evaluator는 실제 실행 결과와 기대 결과를 비교하는 함수이다.
def workflow_evaluator(outputs: dict, reference_outputs: dict) -> dict:
...
평가 기준은 다음과 같다.
- 실제 PASS/FAIL이 기대 결과와 같은가
- PASS 케이스에서는 장소가 선택되었는가
- FAIL 케이스에서는 기대한 실패 이유가 포함되었는가
- Task 누락 때문에 우연히 실패한 것은 아닌가
결과는 점수와 코멘트로 반환한다.
return {
"key": "workflow_requirement_match",
"score": int(passed),
"comment": "...",
}
Evaluator를 사용하면 단순히 실행만 해보는 것이 아니라, 결과 품질을 기준에 따라 판단할 수 있다.
11. Experiment
Experiment는 특정 버전의 Workflow를 Dataset에 대해 실행한 평가 기록이다.
client.evaluate(
baseline_target,
data=DATASET_NAME,
evaluators=[workflow_evaluator],
experiment_prefix="workflow-baseline",
)
수정 후 버전도 같은 Dataset으로 평가한다.
client.evaluate(
fixed_target,
data=DATASET_NAME,
evaluators=[workflow_evaluator],
experiment_prefix="workflow-fixed",
)
이렇게 하면 같은 입력에 대해 baseline과 fixed 결과를 비교할 수 있다.
같은 Dataset
-> baseline 실행 결과
-> fixed 실행 결과
-> 점수 비교
12. LangSmith를 쓰는 이유
AI Workflow는 일반 코드보다 디버깅이 어렵다.
LLM, Tool, Graph, Validator가 함께 동작하기 때문에 어디서 문제가 생겼는지 확인하기 어렵다.
LangSmith를 사용하면 다음을 확인할 수 있다.
- 어떤 입력이 들어왔는지
- 어떤 Plan이 만들어졌는지
- 어떤 Task가 실행되었는지
- 각 Task의 결과가 무엇인지
- 어느 단계에서 예외가 발생했는지
- 수정 전후 품질이 좋아졌는지
즉, LangSmith는 AI 기능의 로그, 디버깅, 평가를 위한 관찰 도구라고 이해할 수 있다.
13. 핵심 정리
- LangSmith는 LangChain, LangGraph 실행 흐름을 추적하고 평가하는 도구이다.
- Trace는 함수나 Workflow의 입력, 출력, 에러를 기록한다.
- @traceable을 사용하면 특정 함수를 LangSmith 추적 대상으로 만들 수 있다.
- run_type="tool"은 개별 Task 실행 추적에 사용했다.
- run_type="chain"은 전체 Workflow 실행 추적에 사용했다.
- 환경 변수로 LANGSMITH_API_KEY, LANGSMITH_TRACING, LANGSMITH_PROJECT가 필요하다.
- API Key는 로그에 그대로 출력하지 않고 마스킹해야 한다.
- baseline과 fixed 버전을 나누면 수정 전후 결과를 비교할 수 있다.
- 실패 Trace를 보면 어떤 Task가 누락되었거나 어느 단계에서 예외가 발생했는지 확인할 수 있다.
- Dataset은 평가에 사용할 입력과 기대 결과 모음이다.
- Evaluator는 실제 결과가 기대 조건을 만족하는지 점수화한다.
- Experiment는 Dataset을 대상으로 특정 버전을 실행한 평가 기록이다.
- 같은 Dataset으로 baseline과 fixed를 평가하면 개선 여부를 비교할 수 있다.
- AI Workflow는 실행 결과뿐 아니라 중간 과정까지 관찰해야 디버깅할 수 있다.
'TIL > [TIL]' 카테고리의 다른 글
| [TIL]Dockerfile, Docker Compose, AWS EC2 기초 (0) | 2026.08.04 |
|---|---|
| [TIL]Linux, Ubuntu, Vim, Docker 기초 (0) | 2026.08.03 |
| [TIL]Agent Safety와 Plan-Execute-Replan Workflow (0) | 2026.07.30 |
| [TIL]Agentic AI, Tool Calling, ReAct, Agent Memory (0) | 2026.07.29 |
| [TIL]FastAPI 파일 브릿지와 LangGraph 기초 (0) | 2026.07.28 |