본문 바로가기

AI·LLM 엔지니어링

〈LangChain 기반 RAG 시스템 구축〉 4편: 프롬프트 설계 + LLM 체인 구성

반응형

 

LangChain 기반 RAG 시스템 구축

📘 LangChain 기반 RAG 시스템 구축

4편. 프롬프트 설계 + LLM 체인 구성 편 

RAG 시스템의 응답 품질은
Retrieval(검색) 40%
Prompt(프롬프트 설계) 40%
Generation(모델 출력 안정화) 20%
정도로 나뉜다.

이 중 프롬프트 설계는 성능과 일관성을 좌우하는 핵심이다.
이번 편에서는 사내 문서 검색 시스템을 기준으로 한
✔ 실전 프롬프트 템플릿
✔ LangChain 체인 구성
✔ vLLM + FastAPI 연동
✔ 문제 해결 사례
까지 전체 구성 방법을 다룬다.


1. RAG에서 프롬프트가 중요한 이유

잘못 설계된 프롬프트는 아래 문제를 만든다:

  • 문서에 없는 내용을 추론해 말함
  • 문서 일부만 참고하고 답변 누락
  • 공식 문체 대신 개인적 말투가 섞임
  • 길거나 불필요한 답변 생성

이를 막기 위해서는 다음 3가지 규칙이 중요하다.

📌 프롬프트 3대 규칙

  1. 역할(Role) 을 정확히 설정
  2. 그라운딩 규칙(Grounding) 을 명시
  3. 출력 포맷(Output Format) 을 고정

2. RAG용 기본 System Prompt 템플릿

아래 템플릿은 사내 문서 검색용으로 최적화한 실전 예시다.


📌 RAG System Prompt (실전용 템플릿)

당신은 회사 내부 문서를 기반으로 정확한 답변을 제공하는 AI Assistant입니다.

[답변 규칙]
1. 제시된 문서(Context) 내용만 기반으로 답변하세요.
2. 문서에 없는 내용은 “문서에서 확인할 수 없습니다”라고 말하세요.
3. 추론, 추측, 상상으로 답변하지 마세요.
4. 중요한 규정은 문서의 원문 표현을 유지하세요.
5. 답변의 끝에 반드시 "출처 문서" 섹션을 포함하세요.

[출력 포맷]
[답변]
요약된 정답

[근거]
문서에서 가져온 핵심 문장 2~4개

[출처 문서]
- 문서명 / 섹션명

3. Retrieval + Prompt + LLM 구성 아키텍처

아키텍처는 아래 흐름으로 구성한다.

User → Query → Retriever → ReRanker → Prompt Template
→ LLM(vLLM) → Answer

이를 LangChain으로 구성하면 다음과 같다.


4. LangChain 기반 RAG 체인 코드 전체

① 프롬프트 템플릿 준비

from langchain.prompts import ChatPromptTemplate

system_prompt = """
당신은 회사 내부 문서를 기반으로 답변하는 AI Assistant입니다.
다음 규칙을 지키세요:

1. Context 내용만 기반으로 답변하세요.
2. 문서에 없는 내용은 ‘문서에서 확인할 수 없습니다’라고 말하세요.
3. 반드시 '출처 문서'를 답변 마지막에 포함하세요.
"""

prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    ("human", "질문: {query}\n\nContext:\n{context}")
])

② Retriever + Reranker 결합

docs = retriever.get_relevant_documents(query)
reranked = reranker.rerank(query, docs)
top_docs = reranked[:4]   # top 4만 사용

③ LLM + 체인 구성

from langchain.chains import LLMChain

chain = LLMChain(
    llm=llm,
    prompt=prompt
)

response = chain.run({
    "query": query,
    "context": "\n\n".join([d.page_content for d in top_docs])
})

5. vLLM + FastAPI로 RAG API 만들기 (실전코드)

아래는 실제 서버에서 많이 사용하는 API 구조다.


📌 vLLM 서버 실행

python -m vllm.entrypoints.openai.api_server \
    --model ./models/llama3.gguf \
    --tensor-parallel-size 1 \
    --gpu-memory-utilization 0.92

📌 FastAPI + LangChain RAG API

from fastapi import FastAPI
from pydantic import BaseModel
from langchain.llms import OpenAI

app = FastAPI()

class Query(BaseModel):
    query: str

@app.post("/rag")
async def rag(query: Query):

    # 1. Retrieve
    docs = retriever.get_relevant_documents(query.query)
    reranked = reranker.rerank(query.query, docs)
    top_docs = reranked[:4]

    # 2. Generate
    response = chain.run({
        "query": query.query,
        "context": "\n\n".join([d.page_content for d in top_docs])
    })

    return {"answer": response}

6. 실무에서 자주 발생하는 문제 + 해결법


문제 ① 답변이 너무 장황함

→ Prompt에 “최대 6줄 이내로 요약” 조건 추가


문제 ② 문서와 다른 잘못된 답변 생성

→ “문서 없으면 모른다고 말하기” 규칙 추가하면 해결됨


문제 ③ 비슷한 문서가 섞여 혼동

→ metadata 필터링 추가

vector_store.similarity_search(
    query,
    filter={"department": "HR"}
)

7. 실제 서비스에서 성능이 가장 잘 나오는 구성 예시

기업 내부 RAG 시스템에서 가장 성능이 뛰어난 조합은 다음과 같다.

문서 분할: Semantic chunking + 80 overlap  
임베딩: bge-m3 또는 E5-large  
Retriever: Hybrid(BM25 + Vector)  
ReRanker: BGE Reranker large  
LLM: Llama3 8B 또는 Qwen2 7B (GGUF)  
Chain: PromptTemplate + LLMChain  
서빙: vLLM + FastAPI  
평가: RAGAS + DeepEval  

실무 환경에서 이 조합이 안정성과 성능 모두 우수했다.


8. 실전 팁 3개


💡 팁 1 — 프롬프트만 바꿔도 정확도가 20~50% 향상된다

Retriever보다 프롬프트 개선 효과가 훨씬 즉각적이다.


💡 팁 2 — 문서 타입별 프롬프트를 따로 만든다

정책, 공지, 메뉴얼 등 문서 성격에 따라
프롬프트를 분기하면 정확도 상승.


💡 팁 3 — “출처 문서” 강제 표기 규칙을 넣으면 Hallucination이 거의 사라진다

문서 근거를 직접 뽑게 하면
모델이 문서 중심으로 사고하게 된다.


9. 다음 편 예고

📘 5편. RAG 평가 자동화 + QA 데이터셋 생성 편

  • RAGAS / DeepEval / LlamaIndex Eval
  • 평가 데이터셋 자동 생성 파이프라인
  • 정확도 개선 사이클 구축(→ 실제 DevOps 적용)

 


🔖 추천 태그

#프롬프트엔지니어링 #LangChain #LLM체인
#RAG프롬프트 #RetrievalAugmentedGeneration
#LLM #vLLM #FastAPI #문서검색AI #엔터프라이즈AI

 

반응형