C.W.K.
Stream
Lesson 04 of 07 · published

Response 구조 — choices, usage, tool_calls

~22 min · response, choices, usage

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

응답에서 텍스트는 completion.choices[0].message.content. completion.message 라고 적으면 안 돼 — choices 는 길이 1 이라도 list. Library 코드에선 n>1 가능성 고려해서 iterate.

usage = billing audit log

매 request 마다 usage.prompt_tokens, completion_tokens, total_tokens 를 request id 와 함께 persist. 두 달 후 bill 이 surprise 일 때 'why' 를 알려주는 게 정확히 이거.

tool_calls 는 null 가능

completion.choices[0].message.tool_calls 는 tool 안 부른 turn 에선 None. Defensive access — getattr(msg, 'tool_calls', None) or [] 같은 패턴이 안전.

Skeleton helper 만들어두면 좋아

Response 마다 {text, finish_reason, prompt_tokens, completion_tokens, tool_calls?} 로 unwrap 하는 헬퍼 1 개 — null-safe, 모든 코드에서 같은 모양으로 사용. Bonus: log line 만들기도 쉬워짐.

Code

Choices 와 usage 검사·json
{
  "id": "chatcmpl-B9MBs8CjcvOU2jLn4n570S5qMJKcT",
  "object": "chat.completion",
  "created": 1741569952,
  "model": "gpt-4.1-2025-04-14",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "Hello! How can I assist you today?",
      "refusal": null,
      "annotations": [],
      "tool_calls": null
    },
    "logprobs": null,
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 19,
    "completion_tokens": 10,
    "total_tokens": 29,
    "prompt_tokens_details": { "cached_tokens": 0 },
    "completion_tokens_details": { "reasoning_tokens": 0 }
  }
}

External links

Exercise

completion 받아서 {text, finish_reason, prompt_tokens, completion_tokens, tool_calls?} dict 반환하는 unwrap_completion(c) 헬퍼 작성. 모든 필드 null-safe. 코드 3 곳에서 사용.

Progress

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

댓글 0

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

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