Langfuse WorkshopClickHouse Workshops

03 프롬프트 관리

작동하는 추적 앱이 있습니다. 시스템 프롬프트는 src/server/support-agent.ts의 SYSTEMPROMPT라는 상수로 존재하며 시스템 메시지로 직접 사용됩니다.

워크숍 자료는 공개 langfuse/langfuse-workshop 저장소에서 유지보수됩니다. 실행 가능한 앱, 체크포인트 분기, 로컬 설정을 위해 저장소를 사용하세요.

이 Markdown 파일 보기

시작점

git checkout checkpoint/03-prompt-management

작동하는 추적 앱이 있습니다. 시스템 프롬프트는 SYSTEM_PROMPT이라는 상수로 src/server/support-agent.ts에 있으며 시스템 메시지로 직접 사용됩니다.

이 장에서는 해당 프롬프트를 Langfuse로 이동하여 버전이 지정되고 UI에서 편집 가능하도록 하며, 요청 시 다시 가져옵니다. 로컬 상수는 Langfuse에 연결할 수 없을 때의 폴백으로 파일에 유지됩니다.

.env에 다음이 있는지 확인하세요:

LANGFUSE_PROMPT_NAME=dad-it-support-agent
LANGFUSE_PROMPT_LABEL=production

프롬프트를 관리하는 이유

시스템 프롬프트를 코드에 유지한다는 것은 모든 프롬프트 변경이 코드 변경이라는 의미입니다: 풀 요청, 검토, 빌드, 배포. Langfuse 프롬프트 관리를 사용하면 프롬프트는 Langfuse에 있으며 — 버전 지정, 레이블 지정, UI에서 편집 가능 — 앱은 요청 시 이를 가져옵니다. 이는 비엔지니어가 프롬프트를 반복할 수 있음을 의미하며, 변경 사항은 릴리스 주기와 무관하게 배포되고, 모든 버전이 보존되고 생성한 추적과 연결됩니다.

Langfuse 프롬프트 문서에서 더 알아보세요.

목표

두 가지 단계:

  1. 시스템 프롬프트를 Langfuse에 게시하여 버전 지정된 복사본이 존재하도록 합니다.
  2. 요청 시 다시 가져오기하고, 각 OpenAI 생성을 이를 생성한 버전에 연결합니다.

1단계 — 프롬프트 게시(Langfuse UI)

프롬프트를 만드는 가장 직접적인 방법은 UI에 수동으로 추가하는 것입니다 — 팀이 향후의 모든 반복에서 사용할 같은 워크플로우입니다.

  1. Langfuse에서 프롬프트 → 새 프롬프트를 엽니다.
  2. dad-it-support-agent로 이름을 지정합니다(당신의 .env의 LANGFUSE_PROMPT_NAME와 일치).
  3. 유형은 text입니다.
  4. src/server/support-agent.ts에서 SYSTEM_PROMPT의 본문을 붙여넣기합니다.
  5. 버전에 production을 레이블로 지정합니다(당신의 .env의 LANGFUSE_PROMPT_LABEL과 일치).
  6. 저장합니다.

Langfuse에서 dad-it-support-agent 프롬프트를 생성합니다.

💡 대체 방법 — 스크립트를 통해 게시합니다. scripts/publish-prompt.ts은 SYSTEM_PROMPT 상수를 Langfuse로 푸시합니다(npm run prompt:publish). 같은 결과입니다.

2단계 — Langfuse에서 프롬프트 가져오기

src/server/support-agent.ts에서 가져오기를 추가합니다:

import { LangfuseClient } from "@langfuse/client";

모듈 범위에서 클라이언트를 구성합니다:

const langfuse = new LangfuseClient();

getPrompt 헬퍼를 추가하여 Langfuse에서 가져오고, 실패 시 null을 반환하여 채팅이 로컬 SYSTEM_PROMPT로 폴백할 수 있도록 합니다:

async function getPrompt() {
  try { return await langfuse.prompt.get(env.langfusePromptName); }
  catch { return null; }
}

runSupportConversation에서 이를 사용합니다 — 가져온 후 가져오기가 null을 반환하면 로컬 상수로 폴백합니다:

const langfusePrompt = await getPrompt();
const systemPrompt = langfusePrompt?.prompt ?? SYSTEM_PROMPT;

시스템 메시지로 systemPrompt을 보냅니다. 아래 몇 줄 아래의 전사에서 이 줄을 찾으세요:

{ role: "system", content: SYSTEM_PROMPT },

그리고 다음으로 변경합니다:

{ role: "system", content: systemPrompt },

이 변경 없이 모델은 로컬 상수를 계속 받습니다 — 다음 단계의 프롬프트 배지는 여전히 나타나지만, Langfuse에서 프롬프트를 편집해도 답변에 영향을 주지 않습니다.

기존 observeOpenAI 호출에 langfusePrompt을 전달하여 생성이 게시된 프롬프트 버전에 연결되도록 합니다 — 실제로 있을 때만:

const openai = observeOpenAI(
  new OpenAI({ apiKey: env.openaiApiKey }),
  langfusePrompt ? { langfusePrompt } : undefined
);

주목할 세 가지:

  • observeOpenAI(new OpenAI(...)) 호출 자체는 변경되지 않았습니다 — 2단계와 같은 인라인 래핑입니다. langfusePrompt를 포함하는 조건부 두 번째 인수만 추가했습니다.
  • 로컬 SYSTEM_PROMPT 상수는 파일에 폴백으로 유지됩니다. Langfuse가 잘못 구성되거나 프롬프트가 아직 게시되지 않았다면, 채팅은 계속 작동합니다 — 단지 그 차례에 프롬프트 배지를 전달하지 않을 뿐입니다.
  • langfusePrompt을 observeOpenAI로 전달하는 것이 그 클라이언트 아래의 모든 생성이 정확히 게시된 버전으로 다시 연결되는 프롬프트 배지를 전달하는 것입니다.

확인

npm run dev

한 가지 질문을 하고, Langfuse에서:

  • 추적을 열고 OpenAI 생성을 클릭합니다. 게시한 버전의 dad-it-support-agent로 연결되는 프롬프트 배지를 표시해야 합니다.
  • dad-it-support-agent의 프롬프트 보기에서 "사용된 위치"로 스크롤하면 당신의 추적이 나타납니다.

top-right의 프롬프트 배지가 dad-it-support-agent · v1로 다시 연결되는 추적된 openai-chat-completion입니다.

정리

프롬프트 관리는 추적 ↔ 프롬프트 루프를 닫는 것입니다. 모든 프롬프트 버전이 보존되고, 모든 생성은 어떤 버전이 이를 생성했는지 알며, 코드 배포와 무관하게 프롬프트를 반복할 수 있습니다.

Langfuse 모범 사례에 맞춰 프롬프트 관리를 구성하는 더 직선적인 방법은 Langfuse 스킬(/langfuse)입니다. 스킬은 각 부분을 수동으로 굴리지 않고도 권장 패턴을 코드베이스에 적용합니다. 이 안내는 스킬이 내부에서 무엇을 하고 있는지 볼 수 있도록 존재합니다.

최종 상태

이는 04-monitoring의 시작점입니다.

이 페이지의 내용

Track your progress?

Optional. We email a link to confirm your address; progress records once you open it.

Please use your work email address, not a personal one.

Progress tracking also requires accepting the current Terms of Service in Privacy settings.

KO