본문 바로가기

AI Agent

LangFlow 완전 가이드 2편 — 기본 튜토리얼 : 챗봇부터 PDF RAG까지

반응형

1편에서 LangFlow 설치와 개념을 다뤘어요.

이번 편은 실제로 손으로 만들어봐요.

이번 편에서 만드는 것:
1. 기본 챗봇
2. 시스템 프롬프트 챗봇
3. PDF RAG 챗봇
4. REST API 배포 + Python/JS 연동

1편 설치 안 하신 분:

pip install langflow
langflow run
# http://localhost:7860 접속

준비 — API 키 등록

첫 번째 플로우 만들기 전에 API 키부터 등록해요.

우상단 프로필 아이콘 클릭
→ Settings
→ Global Variables
→ + Add Variable

이름: ANTHROPIC_API_KEY
값:   sk-ant-xxxxx
Type: Credential
→ Save

Claude 대신 OpenAI 쓸 경우:

이름: OPENAI_API_KEY
값:   sk-xxxxx

이렇게 한 번만 등록하면 모든 플로우에서 재사용돼요.


실전 1 — 기본 챗봇 (10분)

가장 단순한 구조예요. 사용자 입력 → LLM → 출력.

플로우 생성

좌상단 "+ New Flow" 클릭
→ Blank Flow 선택
→ 빈 캔버스 열림

컴포넌트 배치

사이드바에서 검색해서 드래그:

1. Chat Input   (Inputs 카테고리)
2. Language Model (Models 카테고리)  ← 통합 LLM 컴포넌트
3. Chat Output  (Outputs 카테고리)

연결

Chat Input의 오른쪽 점 → Language Model의 왼쪽 점
Language Model의 오른쪽 점 → Chat Output의 왼쪽 점

완성된 구조:
[Chat Input] ──→ [Language Model] ──→ [Chat Output]

포트 색깔이 맞아야 연결돼요. 안 맞으면 선이 그어지지 않아요.

Language Model 설정

Language Model 컴포넌트 클릭:

Model Provider: Anthropic
Model Name:     claude-sonnet-4-6
API Key:        (등록한 ANTHROPIC_API_KEY 선택)
Temperature:    0.7
Max Tokens:     1024

테스트

상단 "Playground" 버튼 클릭
→ 채팅 창 열림
→ "안녕하세요" 입력
→ Claude 응답 확인

완성이에요. 이게 LangFlow의 기본이에요.


실전 2 — 시스템 프롬프트 챗봇 (15분)

역할을 부여한 전문 챗봇이에요. FastAPI 전문가 어시스턴트를 만들어볼게요.

추가 컴포넌트

기본 챗봇에서 컴포넌트 하나 추가:

Prompt Template (Prompts 카테고리) 드래그

구조 변경

[Chat Input] ──→ [Prompt Template] ──→ [Language Model] ──→ [Chat Output]

Chat Input을 Language Model에 직접 연결했던 걸 끊고, Prompt Template을 중간에 삽입해요.

Prompt Template 설정

컴포넌트 클릭 → Template 필드:

당신은 FastAPI와 Python 백엔드 전문 개발자입니다.

다음 규칙을 따르세요:
- 항상 실행 가능한 코드를 제공합니다
- 코드에는 타입 힌트를 포함합니다
- 에러 처리를 포함합니다
- 한국어로 설명합니다

사용자 질문: {user_input}

{user_input} 부분이 Chat Input과 연결되는 포트예요. 중괄호로 감싸면 자동으로 포트가 생겨요.

연결 업데이트

Chat Input → Prompt Template의 user_input 포트
Prompt Template → Language Model
Language Model → Chat Output

테스트

Playground에서:
"JWT 인증 미들웨어 FastAPI로 만들어줘"
→ 전문가 어시스턴트 스타일로 응답

실전 3 — PDF RAG 챗봇 (25분)

핵심 실습이에요. PDF 문서를 업로드하면 그 내용으로 질문에 답하는 챗봇이에요.

RAG 파이프라인에는 두 단계가 있어요:

1단계 — 데이터 로드 (한 번만 실행):
PDF → 텍스트 추출 → 청킹 → 임베딩 → 벡터DB 저장

2단계 — 검색 + 답변 (매 질문마다):
질문 → 임베딩 → 벡터DB 검색 → 관련 내용 추출 → LLM → 답변

템플릿 사용 (빠른 방법)

처음부터 만들기 전에 템플릿으로 시작해요:

+ New Flow
→ Templates 탭
→ "Vector Store RAG" 선택
→ 플로우 자동 생성

이렇게 하면 구조가 이미 완성돼 있어요. API 키만 넣으면 바로 작동해요.

처음부터 만들기 (학습용)

직접 만들면서 구조를 이해해봐요.

1단계 플로우 — 데이터 로드:

필요한 컴포넌트:

1. File (Inputs 카테고리)
2. Split Text (Processing 카테고리)
3. Embedding Model (Models 카테고리)
4. Chroma DB (Vector Stores → Chroma 번들)

연결:

[File] ──→ [Split Text] ──→ [Embedding Model] ──→ [Chroma DB]

컴포넌트 설정:

File 컴포넌트:

지원 형식: PDF, DOCX, TXT, CSV
(파일은 나중에 Playground에서 업로드)

Split Text 컴포넌트:

Chunk Size:    1000  (한 청크의 최대 글자 수)
Chunk Overlap: 200   (청크 간 겹치는 글자 수)
Separator:     \n    (줄바꿈 기준으로 분할)

Embedding Model:

Model Provider: OpenAI
Model Name:     text-embedding-3-small
API Key:        OPENAI_API_KEY

Chroma DB:

Collection Name: my_documents
Persist:         체크 (로컬 저장)

2단계 플로우 — 검색 + 답변:

필요한 컴포넌트:

1. Chat Input
2. Chroma DB (같은 컬렉션)
3. Prompt Template
4. Language Model
5. Chat Output

연결:

[Chat Input] ──────────────────────────────→ [Prompt Template] ──→ [Language Model] ──→ [Chat Output]
                                                     ↑
[Chroma DB (검색)] ←── [Chat Input] (검색어)        │
        │                                           │
        └── (검색 결과) ──────────────────────────→ ┘

Chroma DB는 두 가지 입력을 받아요:

  • 검색 쿼리 (Chat Input에서)
  • 검색 결과를 Prompt Template으로 출력

Prompt Template 설정:

다음 컨텍스트를 기반으로 질문에 답해줘.
컨텍스트에 없는 내용은 "문서에서 찾을 수 없습니다"라고 해.

컨텍스트:
{context}

질문: {question}

포트 연결:

context  ← Chroma DB 검색 결과
question ← Chat Input

PDF 업로드 및 테스트

1단계 실행 (데이터 로드):

1단계 플로우에서:
File 컴포넌트 클릭
→ 파일 선택 버튼
→ PDF 업로드

Chroma DB 컴포넌트 클릭
→ "Run Component" 버튼
→ PDF가 벡터DB에 저장됨
(이 작업은 PDF가 바뀔 때만 다시 하면 됨)

2단계 테스트:

상단 Playground 클릭
→ "이 문서의 핵심 내용이 뭔가요?" 입력
→ PDF 내용 기반 답변 확인

실전 4 — REST API 배포 (10분)

만든 플로우를 API로 배포해서 다른 서비스에서 호출해요.

API 코드 확인

상단 메뉴 → "API" 버튼 클릭
→ 자동 생성된 코드 확인
→ Python / JavaScript / cURL 탭

Flow ID 복사:

API 패널에서 Flow ID 확인
예: 3f2a1b9c-4d5e-6f7a-8b9c-0d1e2f3a4b5c

Python에서 호출

import requests
import os

LANGFLOW_URL = "http://localhost:7860"
FLOW_ID = "your-flow-id-here"      # API 패널에서 복사
LANGFLOW_API_KEY = "your-api-key"  # Settings → API Keys에서 발급

def ask(question: str) -> str:
    """LangFlow RAG 챗봇에 질문"""

    response = requests.post(
        f"{LANGFLOW_URL}/api/v1/run/{FLOW_ID}",
        headers={
            "Content-Type": "application/json",
            "x-api-key": LANGFLOW_API_KEY,
        },
        json={
            "input_value": question,
            "output_type": "chat",
            "input_type": "chat",
        }
    )

    data = response.json()
    return data["outputs"][0]["outputs"][0]["results"]["message"]["text"]

# 사용
answer = ask("이 문서에서 환불 정책이 어떻게 나와 있나요?")
print(answer)

JavaScript/Node.js에서 호출

const LANGFLOW_URL = "http://localhost:7860";
const FLOW_ID = "your-flow-id-here";
const API_KEY = "your-api-key";

async function ask(question) {
  const response = await fetch(
    `${LANGFLOW_URL}/api/v1/run/${FLOW_ID}`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": API_KEY,
      },
      body: JSON.stringify({
        input_value: question,
        output_type: "chat",
        input_type: "chat",
      }),
    }
  );

  const data = await response.json();
  return data.outputs[0].outputs[0].results.message.text;
}

// 사용
const answer = await ask("환불 정책이 어떻게 되나요?");
console.log(answer);

FastAPI 서비스에 붙이기

from fastapi import FastAPI
import requests

app = FastAPI()

LANGFLOW_URL = "http://localhost:7860"
FLOW_ID = "your-flow-id-here"
API_KEY = "your-api-key"

@app.post("/chat")
async def chat(question: str):
    response = requests.post(
        f"{LANGFLOW_URL}/api/v1/run/{FLOW_ID}",
        headers={"x-api-key": API_KEY},
        json={
            "input_value": question,
            "output_type": "chat",
            "input_type": "chat",
        }
    )
    data = response.json()
    answer = data["outputs"][0]["outputs"][0]["results"]["message"]["text"]
    return {"answer": answer}

이제 POST /chat?question=환불정책이 어떻게 되나요? 호출하면 RAG 챗봇이 답해줘요.


흔한 실수와 해결법

포트 연결이 안 됨:
→ 색깔이 다른 포트끼리 연결하려는 것
→ 데이터 타입이 맞는 포트에 연결

Run 했는데 에러:
→ API 키 확인 (등록됐는지, 유효한지)
→ 컴포넌트 오른쪽 상단 빨간 느낌표 클릭 → 에러 메시지 확인

벡터DB 검색 결과가 이상함:
→ Chunk Size 줄이기 (500~700)
→ Chunk Overlap 늘리기 (100~200)
→ 더 좋은 임베딩 모델 사용

Playground에서 응답이 너무 느림:
→ Language Model Temperature 낮추기
→ Max Tokens 줄이기
→ 더 빠른 모델 선택 (claude-haiku-4-5)

3편 예고

3편 — 심화 튜토리얼 1:
- 멀티턴 대화 메모리
- 웹 검색 에이전트
- 커스텀 Python 컴포넌트 작성
- 조건 분기 (If/Else)

4편 — 심화 튜토리얼 2:
- 멀티 에이전트 파이프라인
- MCP 서버 연결
- 프로덕션 배포 (Docker + PostgreSQL)
- 모니터링 설정

 

📌 이전 글: LangFlow 1편 — 개요, 핵심 개념, 환경 세팅

 

LangFlow 완전 가이드 1편 — 개요, 핵심 개념, 환경 세팅

LangFlow가 뭔가AI 파이프라인을 코드로 짜면 이렇게 돼요.from langchain.document_loaders import PyPDFLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain.embeddings import OpenAIEmbeddingsfrom langchain.ve

cell-devlog.tistory.com

📌 다음 글: LangFlow 3편 — 에이전트, 메모리, 커스텀 컴포넌트

 

LangFlow 완전 가이드 3편 — 심화 튜토리얼 : 에이전트, 메모리, 커스텀 컴포넌트

2편에서 기본 챗봇과 PDF RAG를 만들었어요.이번 편은 진짜 쓸만한 걸 만들어요.이번 편에서 만드는 것:1. 대화 메모리 챗봇 — 이전 대화 기억2. 웹 검색 에이전트 — 실시간 정보 검색3. 툴 조합 에

cell-devlog.tistory.com

 

반응형