LLM WikiAccess-protected knowledge portal

WIKI

LLM 0.32: 추론 트레이스·서버사이드 도구·Responses API로 LLM CLI가 에이전트 루프를 지원하는 방법

요약 Simon Willison의 LLM CLI 도구가 2026년 8월 4일 0.32 를 출시했다. 프로젝트 출시 이래 가장 큰 단일 릴리스로, 세 가지 구조적 변화를 담고 있다. 1. 추론 트레이스 노출 추론 모델의 내부 사고 과정을 stderr 로 스트리밍해 파이프라인 중단 없이 확인할 수 있다. 2. OpenAI Responses API 기본화 추론 능력 있는 GPT 5 계열 모델에서 /v1/responses 엔드포인트가

경로human/study/content/ai-frontier/140-llm-0-32-reasoning-traces-server-side-tools-responses-api.md
카테고리Study
태그#ai-review #api #infra #responses #server #side #study #tools

요약

Simon Willison의 LLM CLI 도구가 2026년 8월 4일 0.32를 출시했다. 프로젝트 출시 이래 가장 큰 단일 릴리스로, 세 가지 구조적 변화를 담고 있다.

  1. 추론 트레이스 노출: 추론 모델의 내부 사고 과정을 stderr로 스트리밍해 파이프라인 중단 없이 확인할 수 있다.
  2. OpenAI Responses API 기본화: 추론 능력 있는 GPT-5 계열 모델에서 /v1/responses 엔드포인트가 기본 경로가 됐다. 도구 호출 사이에 추론이 교차 삽입된다.
  3. 서버사이드 도구: WebSearch, CodeInterpreter 같은 도구를 모델 제공자 서버에서 실행한다. 로컬 코드 없이 CLI에서 -T WebSearch만 붙이면 된다.
  4. Message/Part 구조화: 프롬프트 입력과 모델 출력이 Message 객체 목록으로 재설계됐다. 각 메시지는 텍스트·추론·도구 호출·도구 결과·첨부 파일을 Part로 포함한다.
  5. SQLite 로그 전면 재설계: 콘텐츠 주소 기반 메시지 저장소로 교체됐다. 동일 내용의 메시지는 한 번만 기록된다.

배경: LLM CLI란

LLM(llm.datasette.io)은 Simon Willison이 만든 오픈소스 Python CLI 도구이자 라이브러리다. pip install llm으로 설치하면 수백 가지 LLM에 동일한 인터페이스로 접근할 수 있다. 플러그인 시스템으로 OpenAI, Anthropic, Google, Ollama, llama.cpp 등 다양한 제공자를 지원한다.

기본 사용 패턴:

# 프롬프트 실행
llm "프랑스의 수도는 어디인가?"

# 파이프 활용
cat error.log | llm "이 오류의 원인을 분석해줘"

# 대화 세션 시작
llm chat -m gpt-5.6-terra

Python 라이브러리로도 사용한다:

import llm

model = llm.get_model("gpt-5.6-luna")
response = model.prompt("프랑스의 수도는?")
print(response.text())

추론 트레이스: 모델의 생각을 stderr로 보기

추론 모델(o1, o3, Claude Sonnet 5 등)은 응답 전에 내부적으로 "사고" 과정을 거친다. 0.32 이전까지는 이 트레이스가 사용자에게 보이지 않았다.

0.32부터 CLI는 추론 트레이스를 stderr로 스트리밍한다. 이렇게 하면 실제 출력(stdout)을 파이프로 넘기면서 사고 과정을 화면에서 동시에 볼 수 있다.

# 추론 트레이스를 보며 결과를 파일로 저장
llm -m o3 "이 코드의 버그를 찾아줘" < bug.py > result.txt
# stderr: [reasoning] 변수 초기화를 확인해야 한다...
#          [reasoning] 루프 조건이 의심스럽다...

# 추론 트레이스 숨기기
llm -m o3 -R "이 코드의 버그를 찾아줘" < bug.py

# Python에서 숨기기
response = model.prompt("...", hide_reasoning=True)

-R / --hide-reasoning 플래그는 화면 출력만 숨길 뿐, 암호화된 추론 메타데이터는 내부적으로 보존해 후속 대화에서 연속성을 유지한다.


OpenAI Responses API: 도구 호출 사이에 추론 삽입

GPT-4o mini 이하 모델은 /v1/chat/completions를 사용했다. 0.32부터 추론 능력 있는 OpenAI 모델(gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna 등)은 기본으로 /v1/responses 엔드포인트를 사용한다.

차이:

특성/v1/chat/completions/v1/responses
추론 트레이스없음도구 호출 사이에 삽입
도구 호출순차적추론과 교차
서버사이드 도구불가WebSearch, CodeInterpreter
세션 복구수동메시지 이력 기반 자동

기본 모델 변경: 기존 gpt-4o mini에서 gpt-5.6-luna로 교체됐다. llm models default로 확인할 수 있다.


서버사이드 도구: 로컬 코드 없이 도구 실행

서버사이드 도구는 모델 제공자의 서버에서 실행된다. 로컬 함수를 구현할 필요 없이 CLI에서 바로 쓸 수 있다.

# OpenAI Responses API 모델에서 WebSearch 사용
llm -m gpt-5.6-luna -T WebSearch "2026년 한국 GDP 성장률은?"

# CodeInterpreter (메모리 제한 설정)
llm -m gpt-5.6-sol -T 'CodeInterpreter(memory_limit="4g")' \
    "이 CSV를 분석해줘" < data.csv

# Claude 모델: WebSearch, WebFetch, CodeExecution, AnthropicMCP
llm -m claude-sonnet-5 -T WebSearch -T WebFetch "최신 Python 3.14 변경사항은?"

제공자별 지원 서버사이드 도구:

제공자도구
OpenAI (Responses API)WebSearch, CodeInterpreter
AnthropicWebSearch, WebFetch, CodeExecution, AnthropicMCP
# 모델별 서버사이드 도구 목록 확인
llm tools -m gpt-5.6-luna
llm tools -m claude-sonnet-5

Message/Part 구조: 프롬프트와 응답의 재설계

0.32의 가장 큰 내부 변화는 메시지 표현 방식이다. 기존에는 프롬프트와 응답이 단순 문자열이었다. 이제 Message 객체 목록이다.

import llm

model = llm.get_model("gpt-5.6-terra")

# 구조화된 메시지로 프롬프트 구성
messages = [
    llm.Message(role="system", parts=[llm.TextPart("당신은 시니어 DBA입니다.")]),
    llm.Message(role="user", parts=[llm.TextPart("이 슬로우 쿼리를 분석해줘")]),
]

response = model.prompt(messages=messages)

# 응답의 구조 접근
for event in response.stream_events():
    if event.type == "reasoning":
        print(f"[사고] {event.text}")
    elif event.type == "text":
        print(f"[응답] {event.text}")
    elif event.type == "tool_call":
        print(f"[도구 호출] {event.tool_name}: {event.input}")

# 구조화된 메시지 목록 반환
structured = response.messages()

# JSON 직렬화 / 역직렬화
data = response.to_dict()
restored = llm.Response.from_dict(data)

Part 타입:

Part 타입설명
TextPart일반 텍스트
ReasoningPart모델 추론 트레이스
ToolCallPart도구 호출 요청
ToolResultPart도구 실행 결과
AttachmentPart이미지·파일 첨부

도구 루프 제어: 인간 승인과 재개

0.32는 도구 루프를 중단하고 재개하는 기능을 추가했다. 에이전트가 위험한 작업(파일 삭제, API 호출 등)을 시도할 때 인간이 개입할 수 있다.

import llm

def dangerous_delete(file_path: str) -> str:
    """파일을 삭제합니다 — 주의: 되돌릴 수 없습니다."""
    import os
    os.remove(file_path)
    return f"{file_path} 삭제 완료"

model = llm.get_model("gpt-5.6-sol")
response = model.prompt(
    "temp/ 디렉토리를 정리해줘",
    tools=[dangerous_delete],
)

for event in response.stream_events():
    if event.type == "tool_call" and "delete" in event.tool_name:
        # 실행 전 인간 승인 요청
        confirm = input(f"'{event.input}' 삭제하겠습니까? (y/n) ")
        if confirm != "y":
            raise llm.PauseChain("사용자가 삭제를 거부했습니다.")

llm.PauseChain을 발생시키면 루프가 멈추고 메시지 이력이 보존된다. 이후 저장된 이력을 불러와 다른 입력으로 재개할 수 있다.


아키텍처 다이어그램

LLM 0.32 — 에이전트 루프 아키텍처 사용자 / CLI llm -m model -T WebSearch LLM Python Library Message[] + Part[] 직렬화 모델 선택 · 플러그인 로드 모델 제공자 OpenAI /v1/responses Anthropic Messages API Google / Ollama / 기타 서버사이드 도구 WebSearch / WebFetch CodeInterpreter / MCP 추론 트레이스 흐름 • ReasoningPart → stderr 스트리밍 (화면 표시) • TextPart → stdout (파이프 가능) • -R / hide_reasoning=True → 화면 숨김, 메타데이터 보존 도구 루프 제어 ① 모델이 ToolCallPart 생성 ② 로컬 / 서버사이드 도구 실행 ③ ToolResultPart로 결과 반환 ④ raise PauseChain → 루프 중단, 이력 보존 → 나중에 재개 SQLite 로그 콘텐츠 주소 기반 message_tree 뷰 전문 검색(FTS) 모델·도구 필터 sqlite-utils 4.0+ llm logs status 0.32 주요 새 CLI 옵션 llm -m model --options 모델별 옵션 목록 표시 llm openai endpoint URL 임의 OpenAI 호환 엔드포인트에 프롬프트 전송 llm -o service_tier fast|flex 서비스 티어 선택 (flex = 저렴, 지연 감수) llm logs status 스레드·턴 레코드 수 확인 llm -m model -T WebSearch 서버사이드 도구 활성화 llm -R 추론 트레이스 숨기기 llm tools -m model 모델별 도구 목록 llm chat --continue 미완료 대화 이력 기반 재개
LLM 0.32 — 에이전트 루프 아키텍처

SQLite 로그 재설계: 콘텐츠 주소 기반 저장소

기존 SQLite 스키마는 각 응답을 독립적으로 저장했다. 동일한 프롬프트나 응답이 반복될 경우 중복 저장이 발생했다.

0.32의 새 스키마는 콘텐츠 주소 기반이다. 메시지는 내용의 해시값으로 식별되며, 동일 내용은 한 번만 저장된다.

# 로그 상태 확인
llm logs status
# Threads: 1,234
# Turns: 8,901

# 대화 이력 검색
llm logs --search "슬로우 쿼리"

# 특정 모델의 대화만 필터
llm logs --model gpt-5.6-terra

# 특정 도구를 사용한 대화 필터
llm logs --tool WebSearch

# 대화 트리 시각화 (message_tree SQL 뷰)
sqlite3 ~/.config/io.datasette.llm/logs.db \
    "SELECT * FROM message_tree LIMIT 10"

turns.response_json 컬럼에는 원시 제공자 페이로드가 간소화되어 저장된다. 전체 메시지 내용은 별도 콘텐츠 테이블을 참조한다.

마이그레이션: sqlite-utils 4.0 이상이 필요하다. pip install sqlite-utils>=4.0으로 업그레이드한 뒤 llm migrate를 실행하면 기존 로그가 새 스키마로 변환된다.


운영 고려사항

기본 모델 변경 영향

0.32로 업그레이드하면 기본 모델이 gpt-4o mini에서 gpt-5.6-luna로 바뀐다. 이는 비용과 성능 모두 달라짐을 의미한다. 스크립트나 자동화에 기본 모델을 명시하지 않은 경우 예상 외 비용이 발생할 수 있다.

# 현재 기본 모델 확인
llm models default

# 기본 모델 명시적 지정
llm models default gpt-4o-mini  # 이전으로 고정

서버사이드 도구 비용

서버사이드 도구 실행은 제공자 요금이 별도 부과된다. 예를 들어 OpenAI WebSearch는 실행당 과금된다. 자동화 파이프라인에서 반복 실행 시 비용을 모니터링해야 한다.

PauseChain 패턴

llm.PauseChain을 에이전트 안전 설계에 활용할 수 있다.

RISKY_OPERATIONS = {"delete", "drop", "truncate", "rm", "remove"}

def safe_tool_gate(event):
    if event.type == "tool_call":
        tool_lower = event.tool_name.lower()
        if any(op in tool_lower for op in RISKY_OPERATIONS):
            print(f"⚠️  위험 작업 감지: {event.tool_name}({event.input})")
            if input("계속하겠습니까? (y/n): ") != "y":
                raise llm.PauseChain(f"사용자가 {event.tool_name}을 거부했습니다.")

버전 호환성

기능최소 요구사항
Responses APILLM 0.32, openai>=1.84
새 SQLite 스키마sqlite-utils>=4.0
추론 트레이스추론 모델 (o3, GPT-5.6-sol 등)
서버사이드 도구제공자 별도 지원 필요

제한사항과 열린 질문

Open question: llm.PauseChain 기반 인간-루프 승인 패턴이 프로덕션 에이전트 시스템에서 응답 지연(HITL latency)을 어느 수준까지 허용 가능한지는 실제 운영 사례가 쌓여야 답할 수 있다.


References