LLM 실행 추적은 Langfuse로 한다
| 결정일 | 상태 | 원본 |
|---|---|---|
| 2026-07-22 | active | heymoa-ai/docs/decisions/2026-07-22-observability-tool.md |
같은 날 LangSmith로 정했다가 뒤집었다. 설계 전문은 관측성 설계에 있고, 여기에는 왜 뒤집었는가와 언제 다시 뒤집어야 하는가만 적는다.
왜 뒤집었나
LangSmith를 고른 이유는 "의존성 0개, 코드 0줄"이었다. 둘 다 실제로는 성립하지 않았다.
| 근거 | 실제로 확인한 것 |
|---|---|
| 키만 넣으면 된다 | 발급한 키가 403 Forbidden으로 거부됐다. 앱과 SDK 양쪽에서 |
.env에 넣으면 켜진다 | 안 켜진다. Settings는 .env를 읽지만 os.environ에는 안 넣는데, SDK는 os.environ만 본다. docker compose(env_file)나 셸 export로만 켜졌고, README가 안내한 .env 경로는 한 번도 동작한 적이 없다 |
| 전사 원문이 외부로 나간다 | 클라우드 전용이라 피할 방법이 없다 |
세 번째가 결정적이다. 회의 녹취는 우리가 소유한 데이터가 아니다.
Langfuse는 자체 호스팅이 되므로 그 판단을 나중에 되돌릴 수 있는 선택지가 열린다.
지금은 클라우드로 시작하고, 개인정보가 걸리면 LANGFUSE_BASE_URL만 바꿔 옮긴다.
대신 치르는 값
| 값 | 크기 |
|---|---|
| 새 패키지 | 10개 — langfuse + OpenTelemetry 7개 + protobuf + langchain 본체 |
| 코드 | 핸들러를 만들어 callbacks에 넣는 배선 |
langchain 본체는 지금까지 안 쓰던 것이다(langchain-core만 썼다).
OpenTelemetry는 우리가 "만들지 않는 것"으로 뺐던 그것인데, 우리가 계측을 짜는 게 아니라
Langfuse SDK의 내부 구현으로 딸려 온다. 그 차이를 알고 받아들인다.
안 도는 0줄보다 도는 10줄이 낫다가 이 결정의 한 문장 요약이다.
설정은 Settings를 거친다
LangSmith 때는 "SDK가 환경변수를 직접 읽으니 우리가 또 들고 있지 않는다"고 했는데,
그게 .env 경로를 죽인 원인이었다. Langfuse 키는 Settings로 받아 클라이언트에
명시적으로 넘긴다. 관리 지점이 둘이 되는 것보다 안 켜지는 게 나쁘다.
되돌리는 조건
- 자체 호스팅으로 옮긴다 — 실제 회의 녹취가 들어오기 시작하고 개인정보 판단이 필요해질 때.
코드는 안 바뀌고
LANGFUSE_BASE_URL과 compose만 바뀐다 - LangSmith로 돌아간다 — 의존성 10개가 실제로 문제를 일으키고(빌드 시간, 충돌), LangSmith 키 문제가 해결되고, 전사 유출을 감수하기로 정할 때. 셋이 다 성립해야 한다
- 둘 다 뗀다 — LangSmith·Langfuse 없이도 필요한 걸 로그로 다 보게 됐을 때. 지금 로그는 서비스 흐름만 보고 그래프 내부는 안 본다