Ollama가 스트리밍 도구 호출 지원 추가
TL;DR
Ollama는 스트리밍 도구 호출 기능을 도입하여, 채팅 앱이 모델의 토큰 단위 출력을 즉시 받으면서도 날씨 조회나 수학 계산과 같은 함수를 동시에 호출할 수 있게 했습니다.
스트리밍 도구 호출이 가능하게 하는 기능
스트리밍 도구 호출은 모델이 전체 응답이 완료되기 전에 일반 텍스트와 도구 호출을 번갈아 출력할 수 있게 해줍니다. 애플리케이션은 사용자에게 부분적인 내용을 즉시 표시하고, 모델이 도구 호출을 신호할 때 바로 도구(예: API 호출)를 실행할 수 있습니다.
도구 호출을 지원하는 모델
다음은 새 스트리밍 기능과 호환되는 Ollama 호스팅 모델들입니다:
- Qwen 3
- Devstral
- Qwen2.5 및 Qwen2.5‑coder
- Llama 3.1
- Llama 4
- Ollama 모델 라이브러리의 "도구 호출" 필터에 나열된 추가 모델들.
간단한 도구 호출 예제 (날씨)
cURL 요청을 사용해 get_current_weather 함수로 날씨 쿼리를 스트리밍합니다. 모델이 함수를 호출하기로 결정하자마자 응답에는 증분 JSON 조각과 tool_calls 필드가 포함됩니다.
{
"model": "qwen3",
"created_at": "2025-05-27T22:54:58.100509Z",
"message": {
"role": "assistant",
"content": "",
"tool_calls": [{
"function": {
"name": "get_current_weather",
"arguments": {"format": "celsius", "location": "Toronto"}
}
}]
},
"done": false
}
함수 결과가 준비되면 스트림은 계속됩니다.
Python SDK 사용법
Python 라이브러리(pip install -U ollama)는 도구로 일반 Python 콜러블을 수용합니다. 아래 예제에서는 add_two_numbers 함수를 chat()에 stream=True와 함께 전달합니다. 클라이언트는 스트리밍된 텍스트를 출력하고, 도구 호출이 나타날 때마다 이를 감지합니다.
from ollama import chat, ChatResponse
def add_two_numbers(a: int, b: int) -> int:
return a + b
messages = [{"role": "user", "content": "what is three minus one?"}]
response: ChatResponse = chat(model='qwen3', messages=messages, tools=[add_two_numbers], stream=True)
for chunk in response:
print(chunk.message.content, end='', flush=True)
if chunk.message.tool_calls:
print(chunk.message.tool_calls)
출력
[ToolCall(function=Function(name='add_two_numbers', arguments={'a': 3, 'b': 1}))]
JavaScript SDK 사용법
JavaScript 클라이언트(npm i ollama)는 유사하게 작동합니다. 도구 스키마를 정의한 후 ollama.chat()가 텍스트와 도구 호출을 모두 스트리밍합니다.
import ollama from 'ollama';
const addTool = {
type: 'function',
function: {
name: 'addTwoNumbers',
description: 'Add two numbers together',
parameters: {
type: 'object',
required: ['a', 'b'],
properties: {
a: {type: 'number', description: 'The first number'},
b: {type: 'number', description: 'The second number'}
}
}
}
};
async function run(model) {
const messages = [{role: 'user', content: 'What is 2 plus 3?'}];
for await (const chunk of await ollama.chat({model, messages, tools: [addTool], stream: true})) {
if (chunk.message.tool_calls) {
console.log('Tool call:', chunk.message.tool_calls);
} else {
process.stdout.write(chunk.message.content);
}
}
}
run('qwen3').catch(console.error);
출력
Question: What is 2 plus 3?
Tool call: {function: {name: "addTwoNumbers", arguments: {a: 2, b: 3}}}
증분 파서의 동작 방식
배경
이전 Ollama 버전은 전체 모델 출력을 버퍼링하고 JSON으로 파싱한 후 도구 호출을 내보냈습니다. 그러나 도구 호출이 텍스트 어디서든 나타날 수 있기 때문에 스트리밍을 차단했습니다.
증분 파싱 전략
새로운 파서는 각 모델의 템플릿을 읽어 도구 호출 접두사(예: 특수 토큰 또는 문자열)를 인식합니다. 이는 다음과 같은 기능을 가능하게 합니다:
- 모델이 토큰을 스트리밍하면서 부분적인 접두사를 감지할 수 있습니다.
- 일반 콘텐츠와 대기 중인 도구 호출을 분리할 수 있습니다.
- 모델이 예상되는 접두사 없이 순수 JSON 객체를 출력할 경우, 일반 JSON 탐지로 대체할 수 있습니다.
예외 케이스 처리
모델이 이전에 이미 호출한 도구 호출을 반복하거나 설명 텍스트 내에 호출을 포함하는 경우, 파서의 상태 기계는 중복 호출을 방지합니다. 실증적 테스트 결과, 잘못된 또는 중복된 호출이 이제 단일 올바른 호출로 줄어들었습니다.
정확도 향상
이전에는 모델이 내러티브에서 도구 호출을 반복할 경우 두 개의 동일한 도구 호출을 생성할 수 있었습니다. 업데이트된 파서는 접두사를 매칭하고 JSON 파싱 상태를 추적하여 오직 하나의 호출만 내보내도록 보장합니다. 이전 오류의 예시:
[TOOL_CALL] [{"name":"get_conditions","arguments":{"city":"Sydney"}}]
... (text) ...
[{"name":"get_conditions","arguments":{"city":"Sydney"}}]
이제 파서는 단일 tool_calls 항목을 반환합니다.
모델 컨텍스트 프로토콜(MCP) 및 더 큰 윈도우
스트리밍 도구 호출은 Ollama의 모델 컨텍스트 프로토콜(MCP)과 함께 작동합니다. 사용자들은 컨텍스트 윈도우를 32 k 토큰 이상으로 늘리면 도구 탐지의 신뢰도와 생성된 응답의 품질이 모두 향상된다고 보고합니다.
cURL을 통한 컨텍스트 윈도우 조정
curl -X POST "http://localhost:11434/api/chat" -d '{
"model": "llama3.2",
"messages": [{"role": "user", "content": "why is the sky blue?"}],
"options": {"num_ctx": 32000}
}'
참고: 더 큰 윈도우는 메모리 소비를 증가시킵니다.
시작하기
- 최신 Ollama 릴리스 다운로드 – https://ollama.com/download
- 언어별 SDK 설치 – Python용
pip install -U ollama, JavaScript용npm i ollama. - API 호출에서
stream: true플래그를 사용하고, 모델이 호출할 함수를 설명하는tools배열을 포함합니다.
참고
- 스트리밍 도구 호출 구현을 위한 풀 리퀘스트: https://github.com/ollama/ollama/pull/10415
Sources
관련
- Dispatch
- Dispatch
- Dispatch
- Dispatch
- Dispatch