Blog
chatbotragai-agentfine-tuningenterprisellmai

엔터프라이즈 AI 챗봇 구축 가이드 - RAG + Agent + Fine-Tuning 통합

RAG, AI Agent, Fine-Tuning을 결합한 엔터프라이즈 AI 챗봇 구축 방법을 정리합니다. 아키텍처 설계, 대화 관리, 도구 연동, 평가, 운영 모니터링까지 실전 가이드를 제공합니다.

Data Dynamics2026年4月16日12 min read
This post is not yet translated. The original Korean version is shown below.

새 직원이 입사하면 가장 먼저 물어보는 것들이 있습니다. "이 기능 어떻게 신청해요?", "Jira 티켓은 어디서 올려요?", "서버 장애 나면 누구한테 연락해요?" — 이 질문들에 24시간 즉답해주는 동료가 있다면 어떨까요?

엔터프라이즈 AI 챗봇이 바로 그 역할입니다. 단순한 Q&A를 넘어, 사내 문서 검색, Jira·Slack·DB 연동, 반복 업무 자동화까지 처리하는 종합 AI 어시스턴트죠. 이 글에서는 RAG + Agent + Fine-Tuning을 결합한 프로덕션 수준의 챗봇 구축 방법을 다룹니다.

이 글에서 배우는 것

  • 엔터프라이즈 챗봇에 필요한 핵심 요구사항과 기술 스택
  • 의도 분류 → RAG / Agent / SQL 파이프라인으로 자동 라우팅하는 아키텍처
  • 사내 Confluence·GitHub·Notion 문서를 RAG로 연동하고 접근 제어까지 적용하는 방법
  • Fine-Tuning으로 사내 맥락에 최적화된 응답을 만드는 전략
  • 운영 품질을 지속적으로 높이는 피드백 루프 설계

1. 엔터프라이즈 챗봇의 요구사항

단순 FAQ 봇과 엔터프라이즈 챗봇은 요구사항 자체가 다릅니다. 여러 시스템에 걸쳐 있고, 권한 관리도 해야 하고, 할루시네이션은 업무에 직결되니까요.

요구사항설명기술
사내 문서 검색위키, Confluence, 기술 문서 검색RAG
시스템 연동Jira, Slack, DB, 모니터링 연동Agent + Tool Use
도메인 특화 응답사내 기술 스택에 맞는 정확한 응답Fine-Tuning
대화 맥락 유지멀티턴 대화에서 문맥 유지메모리 관리
접근 제어사용자 권한에 따른 정보 접근ACL + 메타데이터 필터
안전성할루시네이션 방지, 유해 콘텐츠 차단가드레일

2. 아키텍처

통합 아키텍처

전체 구조를 먼저 파악하고 각 부분을 살펴봅시다. 사용자 메시지가 들어오면 의도를 파악해 알맞은 파이프라인으로 라우팅되고, 가드레일을 거쳐 응답이 나가는 흐름입니다.

Loading diagram…

의도 분류 → 라우팅

def route_query(user_message: str, context: dict) -> str:
    """사용자 질의를 적절한 파이프라인으로 라우팅"""
    classification = classify_intent(user_message)
    
    if classification == "document_search":
        return rag_pipeline(user_message, context)
    
    elif classification == "system_action":
        return agent_pipeline(user_message, context)
    
    elif classification == "general_chat":
        return chat_pipeline(user_message, context)
    
    elif classification == "data_query":
        return text_to_sql_pipeline(user_message, context)
    
    else:
        return "죄송합니다. 질문을 이해하지 못했습니다. 다시 질문해주세요."

3. RAG 파이프라인 (문서 검색)

사내 문서 인덱싱

Confluence, GitHub, Notion, Slack — 회사마다 문서가 여기저기 흩어져 있습니다. RAG 파이프라인의 첫 번째 임무는 이 모든 소스를 긁어모아 벡터 DB에 넣는 일입니다.

한 문장으로: 사내 문서를 한 곳에 모아 임베딩해두면, 챗봇이 질문에 맞는 관련 문단을 실시간으로 찾아 LLM에게 건네줍니다.

# 다양한 소스에서 문서 수집 및 인덱싱
sources = {
    "confluence": ConfluenceLoader(url="https://wiki.company.com"),
    "github": GitHubLoader(repos=["company/docs", "company/runbook"]),
    "notion": NotionLoader(token="..."),
    "slack_history": SlackLoader(channels=["#engineering", "#incidents"]),
}
 
all_docs = []
for source_name, loader in sources.items():
    docs = loader.load()
    for doc in docs:
        doc.metadata["source"] = source_name
        doc.metadata["access_level"] = get_access_level(doc)
    all_docs.extend(docs)
 
# 청킹 + 임베딩 + 벡터 DB 저장
chunks = text_splitter.split_documents(all_docs)
vectorstore = Chroma.from_documents(chunks, embeddings)

접근 제어 통합 검색

def secure_rag_search(query: str, user: dict) -> str:
    """사용자 권한에 따른 RAG 검색"""
    # 사용자 권한으로 필터 구성
    access_filter = {
        "access_level": {"$in": user["allowed_levels"]},
        "department": {"$in": user["departments"]}
    }
    
    # 필터링된 검색
    docs = vectorstore.similarity_search(
        query, k=5, filter=access_filter
    )
    
    # LLM으로 응답 생성
    context = format_docs_with_sources(docs)
    response = rag_chain.invoke({"context": context, "question": query})
    
    return response

4. Agent 파이프라인 (업무 자동화)

문서 검색만으로는 부족합니다. "Jira 티켓 하나만 열어줘", "오늘 서버 응답 시간 그래프 보여줘" 같은 실행 요청에는 외부 시스템과 직접 연동하는 Agent가 필요합니다.

from langchain_core.tools import tool
 
@tool
def search_jira(query: str) -> str:
    """Jira에서 이슈를 검색합니다."""
    issues = jira_client.search_issues(query, maxResults=5)
    return format_issues(issues)
 
@tool
def create_jira_ticket(title: str, description: str, priority: str) -> str:
    """Jira 티켓을 생성합니다. 사용자 확인 후 실행됩니다."""
    issue = jira_client.create_issue(
        project="ENG", summary=title, description=description, priority=priority
    )
    return f"티켓 생성 완료: {issue.key}"
 
@tool
def query_grafana(metric: str, time_range: str) -> str:
    """Grafana에서 메트릭을 조회합니다."""
    data = grafana_client.query(metric, time_range)
    return format_metrics(data)
 
@tool
def send_slack(channel: str, message: str) -> str:
    """Slack 채널에 메시지를 전송합니다."""
    slack_client.chat_postMessage(channel=channel, text=message)
    return f"메시지 전송 완료: {channel}"
 
# Agent 구성
agent = create_react_agent(
    llm=fine_tuned_llm,  # Fine-Tuned 모델 사용
    tools=[search_jira, create_jira_ticket, query_grafana, send_slack, search_docs],
    prompt="당신은 Data Dynamics의 AI 어시스턴트입니다..."
)

5. Fine-Tuned 모델 통합

기반 모델은 일반적인 지식은 갖추고 있지만, 여러분 회사의 내부 도구·프로세스·사람들은 모릅니다. Fine-Tuning을 통해 사내 맥락을 모델에 녹여넣으면 응답 품질이 확연히 달라집니다.

[Fine-Tuning 효과]

기반 모델 응답: "Spark에서 OOM이 발생하면 메모리를 늘리세요."

Fine-Tuned 모델 응답: "Spark executor OOM 해결 방법:
1. spark.executor.memory를 8g → 16g로 조정 (Airflow DAG: etl_daily.py 수정)
2. 사내 표준 설정: conf/spark-defaults.conf 참고
3. 데이터 스큐 의심 시: #data-team 채널의 '스큐 해결 가이드' 참고
4. 긴급 시: @oncall-data 멘션으로 당직자 호출"

→ 사내 맥락, 도구, 프로세스를 반영한 응답

6. 대화 관리

멀티턴 대화

"아까 말한 그 서버 말인데요" — 이 한마디를 챗봇이 이해하려면 이전 대화 내용을 기억하고 있어야 합니다. 세션 관리와 대화 요약이 멀티턴 경험의 핵심입니다.

class ConversationManager:
    def __init__(self, max_history: int = 20):
        self.sessions = {}  # Redis 기반 세션 관리
        self.max_history = max_history
    
    def get_context(self, session_id: str) -> list:
        """대화 이력 조회 (요약 포함)"""
        history = self.sessions.get(session_id, [])
        
        if len(history) > self.max_history:
            # 오래된 대화 요약
            old = history[:-10]
            summary = llm.invoke(f"다음 대화를 3줄로 요약: {old}")
            history = [{"role": "system", "content": f"이전 대화 요약: {summary}"}] + history[-10:]
            self.sessions[session_id] = history
        
        return history
    
    def add_message(self, session_id: str, role: str, content: str):
        if session_id not in self.sessions:
            self.sessions[session_id] = []
        self.sessions[session_id].append({"role": role, "content": content})

7. 운영 및 모니터링

핵심 지표

챗봇은 한 번 배포하고 끝이 아닙니다. 실제로 얼마나 잘 동작하는지 수치로 보고, 부족한 부분을 계속 개선해야 합니다.

지표설명목표
응답 정확도정확한 답변 비율> 85%
1차 해결률추가 질문 없이 해결> 70%
응답 시간평균 응답 지연< 5초
사용자 만족도피드백 긍정 비율> 80%
할루시네이션율부정확한 응답 비율< 5%
DAU일 활성 사용자 수증가 추세

피드백 루프

Loading diagram…

참고: 엔터프라이즈 챗봇은 "한 번 구축하고 끝"이 아닙니다. 사내 문서가 업데이트되고, 시스템이 변경되며, 사용자의 기대 수준이 높아지므로, 지속적인 개선 체계가 핵심입니다.


마치며 — 핵심 요약

  • 엔터프라이즈 챗봇은 RAG(문서 검색) + Agent(시스템 연동) + Fine-Tuning(사내 맥락)을 결합한 종합 시스템입니다.
  • 의도 분류 → 라우팅 구조가 핵심입니다. 질문 유형을 먼저 파악하고 알맞은 파이프라인을 연결하세요.
  • 접근 제어는 처음부터 설계해야 합니다. 사용자 권한에 따라 검색 결과를 필터링하지 않으면 정보 유출 사고가 납니다.
  • 피드백 루프를 반드시 만드세요. 부정 피드백을 분류해 문서 추가, 프롬프트 개선, Fine-Tuning 데이터 보강으로 연결해야 챗봇이 시간이 지날수록 좋아집니다.
  • 멀티턴 대화에서 세션이 길어지면 오래된 내용은 요약해서 압축하는 전략이 비용과 품질 모두에 유리합니다.
  • 처음엔 RAG만 붙인 MVP로 시작해 사용자 피드백을 모은 뒤, Agent·Fine-Tuning 순서로 단계적으로 확장하는 것이 가장 안전한 접근입니다.

References


— Data Dynamics 엔지니어링 팀