오늘은 이전에 진행했던 PDF 기반 ChatBot 프로젝트를 한 단계 발전시켜, 로컬 모델 실행 환경인 Ollama를 활용한 RAG 프로젝트를 만들어 보았습니다.
이번 프로젝트의 핵심은 크게 두 가지입니다.
- 로컬 모델 연동: OpenAI API뿐만 아니라 Ollama를 통해 로컬 모델을 선택적으로 실행
- 멀티모달 확장: PDF뿐 아니라 이미지까지 인식할 수 있는 챗봇 구현
1. Ollama란?

Ollama는 로컬 환경에서 다양한 오픈소스 LLM(Large Language Model)을 실행할 수 있도록 돕는 런타임입니다.
Ollama의 특징
- 💻 로컬 실행: 인터넷 연결 없이 모델 동작 가능 → 데이터 프라이버시 강화
- ⚡ 간단한 모델 관리: ollama pull <model>로 다운로드, ollama run <model>로 즉시 실행
- 🔌 HTTP API 제공: 서버 모드(ollama serve)로 실행하면 LangChain 등 외부 도구와 손쉽게 연동
- 💰 비용 절감: 클라우드 API 과금 없이 내 하드웨어 리소스를 활용
- 🔄 모델 다양성: Llama3, Mistral, Phi, Qwen 등 원하는 모델을 선택 가능
👉 이번 프로젝트에서는 EEVE-KOREAN-10.8B 모델을 사용하여 한국어 중심의 PDF QA를 시도했습니다.
2. 프로젝트 구조
이번 프로젝트는 Streamlit 기반 웹앱으로 구성되어 있습니다.
- pages/02_Local_RAG.py: PDF 기반 RAG + Ollama 연동
- pages/03_Multi_Modal.py: 이미지 인식 기반 멀티모달 챗봇
앱을 실행하면 사이드바에서 PDF 업로드와 모델 선택이 가능하며, 선택한 모델(OpenAI GPT 시리즈 또는 Ollama 로컬 모델)에 따라 응답 품질/속도를 비교할 수 있습니다.
3. Local RAG 구현 (./pages/02_Local_RAG.py)
주요 흐름
- PDF 업로드 → 캐시에 저장
- Retriever 생성 → 문서 임베딩 후 검색 기능 제공
- 체인 구성 → 프롬프트 + LLM(OpenAI or Ollama) 연결
- 스트리밍 응답 → 토큰 단위 출력으로 실시간 반응
코드 핵심
def create_chain(retriever, model_name='gpt-4o'):
if model_name == 'ollama':
prompt = load_prompt("./prompts/pdf-rag-ollama.yaml")
llm = ChatOllama(model='EEVE-KOREAN-10.8B:latest', temperature=0)
else:
prompt = load_prompt("./prompts/pdf-rag.yaml")
llm = ChatOpenAI(model=model_name, temperature=0)
chain = (
{"context": retriever | format_doc, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
return chain
- ChatOllama를 사용하여 로컬 모델을 선택적으로 실행
- 모델에 따라 프롬프트 YAML을 분리(pdf-rag.yaml, pdf-rag-ollama.yaml)
- chain.stream(user_input)을 통해 실시간 스트리밍 응답 출력
4. 멀티모달 확장 (./pages/03_Multi_Modal.py)
이번에는 이미지 인식 기반 챗봇을 추가했습니다.
- 이미지 업로드 → 캐시에 저장
- 선택한 LLM(OpenAI)과 연결
- MultiModal 객체를 통해 시스템 프롬프트 + 사용자 입력 + 이미지 파일을 조합
코드 예시
def generate_answer(img_file_path, system_prompt, user_prompt, model_name='gpt-4o'):
llm = ChatOpenAI(temperature=0, model=model_name)
multimodal_llm_with_prompt = MultiModal(
llm, system_prompt=system_prompt, user_prompt=user_prompt
)
return multimodal_llm_with_prompt.stream(img_file_path)
👉 기본 시스템 프롬프트는 재무제표 분석용 금융 AI 어시스턴트로 설정되어 있습니다. 사용자는 원하는 역할을 직접 커스터마이징할 수도 있습니다.
5. 실행 방법
streamlit run main.py


6. 결과 및 느낀 점
- 동일한 PDF를 기반으로 OpenAI API vs Ollama 로컬 모델을 비교하면서,
- OpenAI: 응답 품질이 안정적이고 빠름
- Ollama: 속도는 하드웨어 의존적이지만, 비용이 없고 프라이버시 보장
- 이미지 인식 기반 확장은 RAG 범위를 넓혀주었고, 추후 로컬 멀티모달 모델(LLaVA, Qwen-VL 등)을 Ollama로 붙이는 방향도 흥미로울 것 같았습니다.
7. 프롬프트 비교: OpenAI vs Ollama
이번 프로젝트에서 저는 OpenAI API와 Ollama 로컬 모델에 서로 다른 프롬프트를 사용했습니다.
이유는 두 모델의 출력 스타일과 강점이 다르기 때문입니다.
📌 Ollama용 프롬프트 (pdf-rag-ollama.yaml)
_type: "prompt"
template: |
You are an assistant for question-answering tasks.
Use the following pieces of retrieved 'information' to answer the question.
If you don't know the answer, just say that you don't know.
Answer in Korean.
<information>
{context}
</information>
#Question:
{question}
#Answer:
input_variables: ["question", "context"]
- 핵심 포인트
- 단순하고 직관적
- 모델이 과한 포맷팅 없이 질문에 집중할 수 있도록 설계
- Answer in Korean. → 한글 답변 강제
👉 로컬 모델은 출력 안정성이 아직 부족하기 때문에, 불필요한 제약을 최소화해 “질문에 답하는 것”에만 집중하도록 했습니다.
📌 OpenAI용 프롬프트 (pdf-rag.yaml)
_type: "prompt"
template: |
You are an assistant for question-answering tasks.
Use the following pieces of retrieved context to answer the question.
If you don't know the answer, just say that you don't know.
Please write your answer in a markdown table format with the main points.
Be sure to include your source and page numbers in your answer.
Answer in Korean.
#Example Format:
(brief summary of the answer)
(table)
(answer to the question)
**출처**
- page source and page number
#Context:
{context}
#Question:
{question}
input_variables: ["question", "context"]
- 핵심 포인트
- Markdown 표 형식 강제 → 가독성 있는 답변 생성
- 출처 및 페이지 번호 포함 → 근거 중심 답변
- 더 다양한 지시사항을 줘도 OpenAI 모델은 잘 따라오기 때문에, 리포트 형태로 답변을 구성하도록 유도
차이 정리
| 항목 | Ollama 프롬프트 | OpenAI 프롬프트 |
| 출력 형식 | 자유로운 답변 | Markdown 표 형식, 요약 + 출처 포함 |
| 지시 강도 | 최소화 | 상세 지시 (출처, 포맷, 요약) |
| 목적 | 안정적 Q&A 수행 | 구조화된 리포트 생성 |
| 언어 | 한국어 | 한국어 |
👉 요약하자면, Ollama는 “단순하고 확실한 답변”에 집중시키고, OpenAI는 “구조화된 리포트”를 생성하도록 프롬프트를 달리 설계했습니다.
마무리
이번 프로젝트는 클라우드 API와 로컬 LLM을 동시에 지원하는 RAG 파이프라인을 구축해본 경험이었습니다.
- 📄 PDF → RAG → LLM 답변
- 🖼️ 이미지 인식 → 멀티모달 확장
- 🌐 OpenAI ↔ Ollama 로컬 모델 토글
앞으로는 로컬 멀티모달 모델 연동과 프롬프트 최적화를 통해, 완전히 독립적인 AI 에이전트 환경으로 발전시켜 볼 수 있을 것 같습니다 🚀
전체 코드는 다음 링크에서 확인하실 수 있습니다.