6장. RAG 의 원리와 로컬 모델로 옮기기
바꿔 끼우는 짜임
전기 플러그는 규격이 같아서 집에서 쓰던 전기 주전자를 회사 콘센트에도 꽂습니다. 주전자를 새로 사지 않습니다. Ollama 는 OpenAI 와 같은 규격(OpenAI 호환 API)으로 요청을 받으므로, 외부 API 로 쓰던 코드를 거의 그대로 로컬 모델에 꽂을 수 있습니다.
세 카드는 같은 코드가 꽂히는 세 곳입니다. 바뀌는 것은 base_url(서버 주소), api_key, model(모델 이름) 셋뿐입니다. 여기서 플러그가 openai 라이브러리의 코드, 콘센트가 서버입니다. 14장에서 만드는 vLLM 서버도 같은 규격이라 같은 코드로 부릅니다.
바뀌는 세 값
| 값 | 외부 API | Ollama |
|---|---|---|
base_url | 쓰지 않음(라이브러리의 기본 주소) | http://localhost:11434/v1 |
api_key | 환경 변수의 발급받은 키 | 아무 글자("ollama"). 검사하지 않는다 |
model | 공급사의 모델 이름 | qwen2.5:0.5b 처럼 ollama list 의 이름 |
설정만 바꿔 끼우기
설정을 사전으로 빼 두면, 코드의 나머지는 그대로 두고 설정 이름 하나만 바꿉니다.
import os
from openai import OpenAI
SETTINGS = {
"ollama": {"base_url": "http://localhost:11434/v1", "api_key": "ollama", "model": "qwen2.5:0.5b"},
"외부": {"base_url": None, "api_key": os.environ.get("OPENAI_API_KEY", "발급받은_인증키"), "model": "gpt-6-luna"},
}
def make_client(name):
"""설정 이름을 받아 (클라이언트, 모델 이름)을 돌려준다. 클라이언트를 만들 때는 아직 연결하지 않는다."""
s = SETTINGS[name]
return OpenAI(base_url=s["base_url"], api_key=s["api_key"]), s["model"]
client, model = make_client("ollama")
print(client.base_url, model)http://localhost:11434/v1/ qwen2.5:0.5b 가 나옵니다. make_client("외부") 로 바꾸면 같은 client.chat.completions.create(...) 코드가 외부 API 로 갑니다.
코드에 나오는 함수
| 코드 | 쉬운 뜻 |
|---|---|
from openai import OpenAI | OpenAI 의 파이썬 라이브러리에서 클라이언트(요청을 보내는 쪽)를 만드는 틀을 불러온다 |
os.environ.get("OPENAI_API_KEY", "발급받은_인증키") | 환경 변수에서 API 키를 읽는다. 없으면 뒤의 자리표시 글자를 쓴다 |
OpenAI(base_url=..., api_key=...) | 어느 서버로, 어떤 키로 보낼지 정한 클라이언트를 만든다. base_url 이 None 이면 라이브러리의 기본 주소를 쓴다 |
return ..., s["model"] | 클라이언트와 모델 이름 두 개를 한꺼번에 돌려준다 |
client.base_url | 클라이언트가 요청을 보낼 주소다. 출력을 보면 끝에 / 가 붙어 있다 |
이 코드가 뜻하는 것
여행용 멀티 어댑터에 빗대 봅시다. 나라마다 콘센트 모양을 적은 쪽지를 들고 다니다가, 도착한 나라 이름만 고르면 맞는 어댑터를 끼웁니다. 꽂는 전기 주전자(나머지 코드)는 그대로입니다.
| 줄 | 하는 일 | 쉽게 말하면 |
|---|---|---|
SETTINGS = {...} | 서버마다 주소, 키, 모델 이름 세 값을 적어 둔다 | 나라마다 콘센트 모양을 적은 쪽지 |
s = SETTINGS[name] | 고른 이름의 설정을 꺼낸다 | 도착한 나라의 쪽지를 꺼낸다 |
return OpenAI(...), s["model"] | 그 설정으로 클라이언트를 만들어 모델 이름과 함께 돌려준다 | 맞는 어댑터를 끼운다 |
client, model = make_client("ollama") | Ollama 설정을 고른다 | 이번에는 우리 집 콘센트를 고른다 |
print(client.base_url, model) | 정해진 주소와 모델 이름을 찍는다 | 어댑터가 제대로 끼워졌나 본다 |
결과의 http://localhost:11434/v1/ 은 요청이 내 PC 의 Ollama 로 간다는 뜻이고, qwen2.5:0.5b 는 그 서버에서 쓸 모델입니다. 클라이언트를 만들 때는 아직 서버에 연결하지 않으므로, 이 코드는 Ollama 가 꺼져 있어도 같은 결과를 찍습니다.
주의할 점
- 규격이 같아도 모델이 다르면 답이 다릅니다. 바꿔 끼운 뒤에는 같은 질문 묶음으로 다시 채점합니다(실습 6).
- 호환이라도 모든 기능이 같지는 않습니다. Ollama 는
seed,temperature,max_tokens를 받지만, 공급사마다 지원하는 인자와 오류 문구가 조금씩 다릅니다. 예를 들어 GPT 추론 모델은temperature=0을 400 오류로 거절합니다(「외부 API 로 만드는 RAG」 참고). 오류를 받아 처리하는 코드를 둡니다.