독스트링과 타입힌트가 모델에게 주는 설명서
한 줄 요약
모델은 함수 안의 코드를 볼 수 없습니다. 볼 수 있는 것은 이름 · 독스트링 · 인자와 타입 세 가지뿐입니다. 그래서 이 셋이 곧 모델이 읽는 사용 설명서이고, 잘 쓰는 것이 에이전트 품질을 좌우합니다.
1. 모델에게 실제로 무엇이 전달되나
이 함수를 도구로 넘긴다고 해 봅시다.
아래는 4절에서 만들 code/ch03_order_agent.py 의 일부를 미리 보는 것입니다 — 지금 붙여 넣지 않아도 됩니다.
def get_order_status(order_id: str) -> str:
"""주문번호로 주문 상태를 조회한다. 예: 'O001203'"""
oid = order_id.strip().upper()
hit = orders[orders["order_id"] == oid]
if hit.empty:
return f"주문번호 {oid} 를 찾을 수 없습니다."
...
SDK가 이 함수를 뜯어 아래와 같은 명세를 만들어 모델에게 보냅니다. 실제로 생성되는 것을 그대로 옮긴 것입니다.
{
"name": "get_order_status",
"description": "주문번호로 주문 상태를 조회한다. 예: 'O001203'",
"parameters": {
"type": "OBJECT",
"properties": {
"order_id": { "type": "STRING" }
},
"required": ["order_id"]
}
}
어느 줄이 어디로 갔는지 나란히 놓고 보면 이렇습니다.
╳ 는 모델에게 건너가지 않는다는 표시입니다. 위쪽 셋만 건너가고, 함수 본문 네 줄은 한 글자도 건너가지 않습니다.
여기에 없는 것을 확인하세요.
- 함수 본문(
orders[orders["order_id"] == oid]…) → 없습니다 orders가 무슨 데이터인지 → 없습니다- 없는 번호일 때 무슨 문장이 나오는지 → 없습니다
모델이 아는 것은 "get_order_status 라는 게 있고, 문자열 order_id 를 받고, 주문 상태를 조회한다더라" 가 전부입니다.
독스트링은 첫 줄만이 아니라 전체가 들어갑니다. 그래서 모델이 읽을 필요 없는 말은 독스트링이 아니라
#주석으로 적어야 합니다. 독스트링에 적은 것은 전부 호출할 때마다 요금을 내고 함께 나갑니다. (실습 파일의get_order_status독스트링에 있는[중요] ...세 줄은 여러분에게 설명하려고 넣은 것이라, 실제 서비스라면 주석으로 내려야 합니다.)
2. 어디서 무엇이 왔나
| 명세의 항목 | 파이썬 코드의 어디에서 왔나 |
|---|---|
"name" |
함수 이름 get_order_status |
"description" |
독스트링 전체 |
"properties" 의 키 |
인자 이름 order_id |
"type": "STRING" |
타입힌트 order_id: str |
"required" |
기본값이 없는 인자 |
타입힌트(type hint) 는
order_id: str처럼 "이 자리에는 문자열이 들어온다" 고 적어 두는 메모입니다. 화살표 표기-> str은 "돌려주는 값이 문자열" 이라는 뜻이고요. 2장에서 "지금은 친절한 주석"이라고 했던 그것입니다.
2장에서 "타입힌트는 지금은 메모지만 3장에서 중요해진다"고 예고했던 게 이것입니다. order_id: str 의 str 이 모델에게 전달되는 실제 정보입니다.
타입힌트를 안 쓰면 어떻게 될까요? 타입 정보가 빠지거나 오류가 납니다. 도구로 쓸 함수에는 인자마다 타입힌트를 반드시 붙이세요.
str,int,float,bool정도면 충분합니다.
3. 독스트링을 잘 쓰는 법
독스트링은 모델에게 주는 설명문입니다. 사람이 읽을 주석이 아니라, 읽고 판단할 상대가 모델이라고 생각하고 쓰세요.
✗ 나쁜 예
아래는 4절에서 만들 code/ch03_order_agent.py 의 일부를 미리 보는 것입니다 — 지금 붙여 넣지 않아도 됩니다.
def get_order_status(order_id: str) -> str:
"""상태 조회"""
무엇의 상태인지, order_id 가 어떻게 생겼는지 모릅니다. 모델은 언제 이걸 써야 할지 판단하지 못합니다.
✓ 좋은 예
아래는 4절에서 만들 code/ch03_order_agent.py 의 일부를 미리 보는 것입니다 — 지금 붙여 넣지 않아도 됩니다.
def get_order_status(order_id: str) -> str:
"""주문번호로 주문 상태를 조회한다. 예: 'O001203'"""
- 무엇을 하는지 — 주문 상태 조회
- 언제 쓰는지 — 주문번호가 있을 때
- 인자가 어떻게 생겼는지 —
'O001203'형식
예시 한 줄이 특히 효과적입니다. 모델이 사용자 문장에서 O001203 을 정확히 뽑아내는 데 직접 도움이 됩니다.
도구가 여러 개일 때는 더 중요합니다
4장에서 도구 두 개를 함께 씁니다. 그때 모델은 독스트링만 보고 어느 쪽을 쓸지 고릅니다.
아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.
def get_product_info(product_name: str) -> str:
"""승승장구몰이 파는 상품의 가격·평점·카테고리를 조회한다.
상품명 일부만 넣어도 된다. 예: '스마트워치'
"""
def search_web(query: str) -> str:
"""인터넷에서 최신 정보를 검색한다.
시장 동향·경쟁 제품처럼 사내 데이터에 없는 내용에 쓴다."""
"사내 데이터에 없는 내용에 쓴다" — 이 한 문장이 경계선을 그어 줍니다. 이런 문장이 없으면 모델은 자사 상품 가격도 웹에서 찾으려 할 수 있습니다.
도구 설명은 "이건 이럴 때 쓴다" 뿐 아니라 "이건 이럴 때 안 쓴다" 도 적어 주는 편이 좋습니다.
4. 체크리스트 — 도구를 만들 때마다
아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.
def function_name(arg: Type) -> str:
"""① 무엇을 하는가 (한 문장)
② 언제 쓰는가 / 언제 안 쓰는가
③ 인자 예시
"""
| 항목 | 확인 |
|---|---|
| 함수 이름이 하는 일을 드러내는가 | get_order_status ✓ / func1 ✗ |
| 모든 인자에 타입힌트가 있는가 | order_id: str |
| 독스트링 첫 줄이 하는 일을 말하는가 | |
| 인자 예시가 들어 있는가 | 예: 'O001203' |
| 도구가 여럿이면 경계선을 적었는가 | "사내 데이터에 없는 내용에 쓴다" |
| 반환값이 문자열인가 | 모델은 문자열을 읽는다 |
5. 반환값도 설명입니다
빠뜨리기 쉬운 지점입니다. 함수가 돌려주는 문자열도 모델이 읽습니다.
아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.
return f"주문 {r.order_id} | 고객 {customer} | {r.product_name} {r.quantity}개 " \
f"| {int(r.amount):,}원 | 주문일 {r.order_date} | 상태 '{r.status}'"
주문 O001203 | 고객 오지우 | 승승 스마트워치 Fit 5 1개 | 159,000원 | 주문일 2026-05-14 | 상태 '배송완료'
항목마다 이름을 붙여 돌려준 덕분에 모델이 "상태가 배송완료구나"를 정확히 읽습니다. 만약 이렇게 돌려줬다면 어땠을까요?
아래는 개념 설명용 코드입니다 — 실습 파일에 넣지 않습니다.
return "O001203 오지우 승승 스마트워치 Fit 5 1 159000 2026-05-14 배송완료" # ✗
숫자 1 이 수량인지 무엇인지, 159000 이 단가인지 총액인지 모델이 헷갈립니다.
도구의 반환값은 "다음 사람이 읽을 보고서"라고 생각하고 쓰세요. 여기서 다음 사람은 모델입니다. 6장에서 문서 검색 결과를 돌려줄 때, 8장에서 담당자(워커)가 팀장(플래너)에게 보고할 때 — 계속 같은 원칙이 적용됩니다.
6. 명세를 직접 확인해 보기
궁금하면 직접 찍어 볼 수 있습니다.
새 파일을 만드세요 —
agentic_ai/code/check_spec.py명세만 찍어 보는 확인용 파일입니다.
ch03_order_agent.py에는 넣지 마세요 — 넣으면 진짜 도구 함수가 아래의 빈 껍데기로 덮어써져 실습이 깨집니다.
from google.genai import types
def get_order_status(order_id: str) -> str:
"""주문번호로 주문 상태를 조회한다. 예: 'O001203'"""
... # 본문은 명세에 안 들어가므로 비워 둔다
d = types.FunctionDeclaration.from_callable_with_api_option(callable=get_order_status)
print(d.model_dump_json(indent=2, exclude_none=True))
python code/check_spec.py 로 돌립니다. 독스트링을 고치고 다시 찍어 보세요. 모델에게 전달되는 내용이 어떻게 달라지는지 눈으로 확인하면, 독스트링을 신중하게 써야 하는 이유를 알 수 있습니다.
핵심 정리
- 모델은 함수 본문을 볼 수 없습니다. 이름 · 독스트링 · 인자와 타입만 봅니다.
- SDK가 그 셋으로 명세(JSON) 를 만들어 모델에게 보냅니다.
- 타입힌트는 필수입니다. 인자마다
str,int같은 타입을 붙이세요. - 독스트링에는 무엇을 하는지 · 언제 쓰는지 · 인자 예시를 적습니다. 도구가 여럿이면 "언제 안 쓰는지" 도 적습니다.
- 반환값 문자열도 모델이 읽습니다. 항목마다 이름을 붙여 돌려주세요.
- 다음 절부터 실제로 도구를 만들어 봅니다.