모델을 바꿔도 코드는 그대로 Ollama API로 로컬 LLM 다루기
보통 AI 모델을 바꾸려면 코드도 함께 수정해야 할 것 같지만, Ollama 를 사용하면 실제로는 model 이름 한 줄만 바꾸면 되는 경우가 많다.
예를 들어 오늘은 Llama 모델을 쓰다가, 내일 더 좋은 모델이 나오면 모델 이름만 바꿔 테스트할 수 있다. 서비스 코드는 거의 그대로 유지된다.
이게 생각보다 굉장히 큰 장점이다.
많은 사람들이 Ollama를 단순히 “터미널에서 AI랑 대화하는 프로그램” 정도로 생각한다. 하지만 실제로 사용해 보면 Ollama의 핵심은 단순 모델 실행기가 아니라 “여러 LLM을 동일한 방식으로 사용할 수 있게 해주는 REST API 서버” 에 가깝다.
이 글에서는 Ollama가 제공하는 API가 무엇인지, 왜 “모델을 바꿔도 코드는 그대로”라는 말이 가능한지, 그리고 실제로 어떻게 사용하는지를 입문자 기준으로 차근차근 정리해본다.
먼저 알아둘 용어 몇 가지
LLM
LLM(Large Language Model)은 우리가 흔히 말하는 대화형 AI 모델이다.
예를 들면:
- Llama
- Gemma
- Qwen
- Mistral
같은 모델들이 모두 LLM의 종류다.
API
API는 프로그램끼리 대화하는 규칙이다.
쉽게 말하면 “이 형식으로 요청하면, 이런 형식으로 답해줄게” 라는 약속이다.
REST API
REST API는 웹에서 가장 흔하게 사용하는 API 방식이다.
인터넷 주소(URL)에 HTTP 요청을 보내고 응답을 받는 구조다.
우리가 웹 브라우저로 사이트에 접속하는 것도 기본 원리는 비슷하다.
Ollama API가 하는 일

Ollama 를 설치하고 실행하면, 단순히 AI 모델만 뜨는 것이 아니다.
실제로는 내 컴퓨터 안에 작은 API 서버도 함께 실행된다.
기본 주소는 보통 다음과 같다.
http://localhost:11434
여기서:
- localhost 는 “내 컴퓨터 자신”
- 11434 는 Ollama가 사용하는 포트 번호
라고 생각하면 된다.
즉 내 프로그램은 이 주소로 HTTP 요청을 보내서 모델과 대화하게 된다.
아래와 같이 브라우저 연결 할 경우 Ollama is running 메시지를 확인 할 수 있다.

구조를 그림으로 보면 이렇다
내 프로그램
↓ HTTP 요청
Ollama API 서버
↓
Llama / Gemma / Qwen 같은 모델
핵심은 여기다.
내 프로그램은 “어떤 모델이 내부에서 동작하는지”를 크게 신경 쓰지 않는다.
그냥:
"Ollama API에 요청을 보낸다"
만 알면 된다.
모델별 차이는 대부분 Ollama가 내부에서 처리한다.
왜 이 구조가 중요한가
원래 로컬 LLM 생태계는 꽤 복잡했다.
모델마다
- 설치 방법
- 실행 방식
- 메모리 설정
- 라이브러리
- 응답 형식
이 전부 달라지는 경우가 많았다.
즉 모델을 교체하면 코드도 함께 수정해야 하는 경우가 많았다.
그런데 Ollama 는 이 차이를 상당 부분 추상화한다.
그래서 개발자 입장에서는:
모델 이름만 바꾸기
수준으로 여러 모델을 교체해가며 테스트할 수 있다.
준비하기
1. Ollama + 모델 설치
먼저 Ollama 를 설치해야 한다.
간단한 명령어 두줄로 윈도우에서 Ollama + qwen 모델까지 설치 완료
irm https://ollama.com/install.ps1 | iex // Ollama 설치
ollama run qwen2.5:3b // qwen 모델 실행 명령이지만 설치 + 실행

현재 설치된 모델 확인
현재 어떤 모델이 설치되어 있는지 확인하려면
curl http://localhost:11434/api/tags
를 실행하면 된다.
그러면 현재 사용 가능한 모델 목록이 JSON 형태로 반환된다.
모델에게 질문 보내기
이제 실제로 모델에게 질문을 보내보자.
샘플 코드: https://github.com/JsonCorp/ollama-api-test.git
GitHub - JsonCorp/ollama-api-test
Contribute to JsonCorp/ollama-api-test development by creating an account on GitHub.
github.com
/api/chat
가장 많이 사용하는 API 중 하나다.
대화(chat) 형식 요청을 처리한다.
try {
const endpoint = currentMode === 'chat' ? '/api/chat' : '/api/generate';
const body = currentMode === 'chat'
? { model, messages: [{ role: 'user', content: text }], stream: false }
: { model, prompt: text, stream: false };
const res = await fetch(`${OLLAMA_HOST}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
if (!res.ok) {
const errText = await res.text();
throw new Error(`HTTP ${res.status}: ${errText}`);
}
const data = await res.json();
const reply = currentMode === 'chat'
? data.message?.content
: data.response;
loadingDiv.innerHTML = `<div class="label">🤖 ${model}</div>${escapeHtml(reply || '(응답 없음)')}`;
} catch (err) {
loadingDiv.innerHTML = `<div class="label">⚠️ 오류</div>요청 실패: ${escapeHtml(err.message)}`;
}



모델의 응답 품질 이슈로 일부 부정확한 결과가 확인되었다. 다만 본 테스트에서는 해당 케이스는 범위에서 제외하였다.

요청 구조 이해하기
여기서 중요한 항목은 몇 개 없다.
model
사용할 모델 이름이다.
"model": "qwen2.5:3b"
messages
대화 내용이다.
"messages": [
{
"role": "user",
"content": "질문 내용"
}
]
- role=user → 사용자의 질문
- role=assistant → AI 응답
- role=system → AI 행동 지시
같은 의미를 가진다.
stream
응답을 어떻게 받을지 정하는 옵션이다.
"stream": false
로 설정하면 답변이 완성된 뒤 한 번에 반환된다.
Python으로 호출하기
같은 요청을 Python으로 하면 이렇게 된다.
import requests
response = requests.post(
"http://localhost:11434/api/chat",
json={
"model": "llama3.2",
"messages": [
{
"role": "user",
"content": "지구에서 가장 깊은 바다는 어디야?"
}
],
"stream": False,
},
)
print(response.json()["message"]["content"])
중요한 점은 curl이든 Python이든 요청 형식은 동일하다 는 것이다.
HTTP + JSON 구조만 맞으면 어떤 언어에서도 사용할 수 있다.
이 글의 핵심은 모델을 바꿔도 코드는 거의 그대로다
이제 진짜 중요한 부분이다.
이번에는 같은 요청을 Gemma 모델로 보내보자.
curl http://localhost:11434/api/chat -d '{
"model": "gemma3",
"messages": [
{ "role": "user", "content": "지구에서 가장 깊은 바다는 어디야?" }
],
"stream": false
}'
앞선 요청과 비교해 보면 달라진 건 사실상 이것뿐이다.
"model": "qwen2.5:3b"
↓
"model": "gemma3"
주소도 같고
/api/chat
메시지 구조도 같고, 응답 방식도 동일하다.
즉 “모델 이름만 바꿔 여러 모델을 교체해가며 사용할 수 있다” 는 의미다.
Python에서는 더 강력해진다
이 구조를 함수로 만들면 장점이 더 명확하게 드러난다.
import requests
def ask(model, question):
response = requests.post(
"http://localhost:11434/api/chat",
json={
"model": model,
"messages": [
{
"role": "user",
"content": question
}
],
"stream": False,
},
)
return response.json()["message"]["content"]
print(ask("llama3.2", "양자 얽힘을 설명해줘"))
print(ask("gemma3", "양자 얽힘을 설명해줘"))
핵심은 함수가 바뀌지 않는다는 점이다.
모델 이름만 교체해서:
- 응답 스타일 비교
- 성능 비교
- 속도 비교
- 메모리 사용량 비교
를 쉽게 할 수 있다.
사용자가 모델을 직접 선택하게 만들 수도 있다
예를 들어 웹 화면에서:
- Llama
- Gemma
- Qwen
중 하나를 선택하게 만들고, 그 값을 그대로 model 항목에 넣으면 된다.
즉:
사용자 선택
↓
model 값 변경
↓
같은 API 호출
만으로 여러 모델 지원 기능이 완성된다.
이게 Ollama 의 꽤 강력한 부분이다.
/api/chat 과 /api/generate 차이

입문 단계에서는 /api/chat 하나만 알아도 충분하다.
다만 둘 차이는 알고 있으면 좋다.
/api/chat
대화 구조 기반 API다.
messages
role
assistant
system
같은 채팅 개념을 지원한다.
/api/generate
단일 프롬프트 기반 생성 API에 가깝다.
조금 더 단순한 형태다.
예를 들면:
{
"model": "llama3.2",
"prompt": "파이썬을 설명해줘"
}
처럼 사용한다.
스트리밍(Stream)이란?
앞 예제들에는 모두:
"stream": false
가 들어갔다.
이 옵션을 제거하면 Ollama는 응답을 조금씩 나눠서 반환한다.
즉:
안
안녕
안녕하세요
안녕하세요!
처럼 토큰이 생성되는 즉시 전달된다.
챗봇 화면에서 글자가 타이핑되는 느낌과 비슷하다.
다만 입문 단계에서는 조각난 응답을 합쳐야 하므로, 처음에는 stream: false가 훨씬 다루기 쉽다.
OpenAI 형식도 지원한다
시험 제외!!
Ollama 는 OpenAI 호환 API도 제공한다.
즉 기존 ChatGPT/OpenAI 코드 일부를 거의 그대로 사용할 수 있다.
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama",
)
response = client.chat.completions.create(
model="llama3.2",
messages=[
{
"role": "user",
"content": "안녕!"
}
],
)
print(response.choices[0].message.content)
즉:
OpenAI SDK
↓
Ollama 서버
↓
로컬 모델
구조도 가능하다.
결국 Ollama의 진짜 장점은 “표준화”다
많은 사람들이 Ollama 의 장점을:
로컬에서 AI 실행 가능
정도로만 생각한다.
물론 그것도 맞다.
하지만 실제로 사용해 보면 더 중요한 건:
- 여러 모델 지원
- 동일한 REST API
- 모델 교체 용이성
- 서비스 코드 단순화
- 모델 종속성 감소
같은 “표준 인터페이스 역할”에 있다.
마무리
Ollama API의 핵심은 생각보다 단순하다.
정해진 주소에:
- model 이름
- 메시지 내용
을 넣어 요청하면, 어떤 모델이든 거의 같은 방식으로 응답을 받을 수 있다.
'AI 관련 자료' 카테고리의 다른 글
| Claude Code MEMORY.md는 어떻게 동작할까? (0) | 2026.06.03 |
|---|---|
| 사내 서버에 로컬 LLM 띄워서 대시보드에 연동해본 후기 (0) | 2026.05.23 |
| 같은 프롬프트, 다른 모델 — Claude Sonnet 4.6 vs Opus 4.7 Android 코드 품질 비교 (0) | 2026.05.16 |
| 클로드 디자인 결과문 13분만에 안드로이드 앱 코드 생성 및 앱 실행까지 (0) | 2026.05.16 |
| 클로드 디자인 결과물 클로드 코드로 작업하기 - 간단 설명 (0) | 2026.05.12 |