C.W.K.
Stream
Lesson 01 of 05 · published

최소 에이전트: 프레임워크 전에 루프부터

~32 min · python, minimal-agent, loop

Level 0Observer
0 XP0/40 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

루프를 한 번은 손으로 만들어봐

프레임워크 쓰기 전에 루프를 직접 만들어봐. 프레임워크가 나빠서가 아니라, 프레임워크가 가장 중요한 장치를 감춰버리기 때문이야. provider는 final text나 tool call을 돌려준다. 애플리케이션은 tool call을 실행하고 결과를 다시 넣는다. 그게 기계야.

직접 만든 loop는 프레임워크가 대신 구해주지 못하는 세 가지 실패 지점을 가르쳐. 나쁜 tool schema, 나쁜 tool result formatting, 빠진 stop policy.

루프의 모양

message list에서 시작해. model에 tool definition과 함께 보낸다. model이 tool call을 돌려주면 신뢰된 코드에서 실행한다. model의 요청과 tool 결과를 state에 붙인다. 반복한다.

아래 구현은 일부러 provider-neutral하게 쓴 거야. 실제 API의 메시지 모양은 다르지만 control flow는 같다.

도구 실행은 모형 밖에 둬

모형은 tool call을 요청할 뿐이고, 애플리케이션이 허용 여부를 판단하고, 실행하고, 에러를 잡고, 로그를 남기고, 간결한 결과를 돌려줘야 해. 이 분리가 있어야 디버깅과 권한 통제가 가능해진다.

Code

안전한 tool execution이 있는 최소 loop·python
import json
from dataclasses import dataclass

@dataclass
class ToolCall:
    id: str
    name: str
    arguments: dict

def safe_execute(tool_call, registry):
    if tool_call.name not in registry:
        return {"ok": False, "error": f"Unknown tool: {tool_call.name}"}
    try:
        return {"ok": True, "data": registry[tool_call.name](**tool_call.arguments)}
    except Exception as exc:
        return {"ok": False, "error": str(exc)}

def run_agent(task, model, tool_registry, max_steps=10):
    messages = [{"role": "user", "content": task}]

    for _ in range(max_steps):
        response = model(messages=messages, tools=list(tool_registry))
        if response.final_text:
            return response.final_text

        messages.append(response.as_message())
        for call in response.tool_calls:
            result = safe_execute(call, tool_registry)
            messages.append({
                "role": "tool",
                "tool_call_id": call.id,
                "content": json.dumps(result),
            })

    return "Stopped before completion: max_steps reached."

External links

Exercise

가짜 tool 두 개 get_time(), add(a, b)로 toy agent loop를 만들어봐. 실제 모델은 부르지 말고 tool call 하나를 가진 mock response를 써.
Hint
목표는 모델 호출이 아니라 control flow야. tool error가 uncaught exception으로 터지지 않고 data로 돌아오게 해.

Progress

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

댓글 0

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

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