본문 바로가기
C.W.K.
Stream
Lesson 04 of 07 · published

The Tool Loop — 3 phase per turn

~22 min · tool-loop, multi-turn

Level 0Tokenizer
0 XP0/54 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

tool loop 의 한 cycle 은 세 단계야. 먼저 context 를 보내 모델에게 tool_calls 또는 텍스트를 받아. 텍스트면 끝내고, tool_calls 면 각 handler 를 실행해 결과를 모아. 그 결과를 다시 모델에 보내 텍스트나 다음 tool_call 을 받고, tool_call 이 없어질 때까지 반복해.

세 단계를 코드에 그대로 드러내

  1. 1단계: responses.create(input, tools=[...]) 를 호출하고 output 이 tool_call 인지 텍스트인지 확인해.
  2. 2단계: 각 tool_call 의 name 과 arguments 로 handler 를 실행하고 결과를 저장해.
  3. 3단계: 결과를 Responses 의 function_call_output 또는 Chat Completions 의 tool role 메시지로 보내. 텍스트가 나올 때까지 반복해.

반복 횟수에는 반드시 상한을 둬

max_tool_iterations=10 처럼 명시적인 상한을 설정해. 잘못된 prompt 는 도구끼리 끝없이 오가는 loop 를 만들 수 있어. 상한에 닿으면 분명한 오류와 함께 중단하는 circuit breaker 로 사용해.

매 단계를 기록해야 다시 재생할 수 있어

iteration 마다 tool, arguments, 결과를 JSONL 에 기록해. 그러면 실제 loop 를 CI 에서 replay 하는 운영 테스트의 입력으로 쓸 수 있어.

Code

Full tool loop (Responses)·python
import json
from openai import OpenAI

client = OpenAI()

def get_weather(location, units="celsius"):
    return {"location": location, "temperature": 22, "condition": "sunny", "units": units}

def search_news(query):
    return [{"title": f"News about {query}", "url": "https://news.example.com"}]

TOOLS_MAP = {"get_weather": get_weather, "search_news": search_news}

tools = [
    {"type": "function", "name": "get_weather", "description": "Get current weather",
     "parameters": {"type": "object", "properties": {"location": {"type": "string"},
     "units": {"type": ["string", "null"], "enum": ["celsius", "fahrenheit"]}},
     "required": ["location"], "additionalProperties": False}, "strict": True},
    {"type": "function", "name": "search_news", "description": "Search recent news",
     "parameters": {"type": "object", "properties": {"query": {"type": "string"}},
     "required": ["query"], "additionalProperties": False}, "strict": True},
]

input_items = [{"role": "user", "content": "Weather in Tokyo and any AI news?"}]

while True:
    response = client.responses.create(model="gpt-5.4", tools=tools, input=input_items)
    input_items.extend(response.output)
    tool_calls = [i for i in response.output if i.type == "function_call"]
    if not tool_calls:
        print(response.output_text)
        break
    for tc in tool_calls:
        result = TOOLS_MAP[tc.name](**json.loads(tc.arguments))
        input_items.append({
            "type": "function_call_output",
            "call_id": tc.call_id,
            "output": json.dumps(result),
        })

External links

Exercise

get_weather, get_news, get_calendar 세 개의 가짜 tool 로 loop 를 만들어. 반복 상한은 5로 두고, 매 단계의 iteration 번호와 호출된 tool, 모델의 reasoning text 를 기록해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.