@tool 을 세 단계 깊이로 쓸 때 모델에게 실제로 전달되는 도구 정보(이름, 설명, 입력 JSON 스키마)가 어떻게 달라지는지,
그리고 실패를 예외 대신 문자열로 돌려주면 무엇이 달라지는지를 한 단계씩 넘겨 봅니다.
두 파일은 모델을 부르지 않으므로 화면의 출력과 스키마는 모두 실제로 실행해 얻은 값입니다.
모델이 도구에 대해 아는 것은 ③의 세 칸뿐이고, 도구를 부른 뒤 아는 것은 ④가 돌려준 값뿐입니다. 초록 점선은 입력 스키마가 ③으로 안내문이 되는 동시에 ④에서 검문소로 한 번 더 쓰인다는 뜻입니다. 플레이어의 단계마다 해당하는 칸이 파랗게 표시됩니다.
플레이어에서 본 네 도구가 모델에게 보내는 정보를 한 표로 모았습니다. 마지막 열은 tool_error.py 의 같은 이름 도구입니다.
단계 1 add | 단계 2 calculator | 단계 3 search_employee | tool_error.py search_employee | |
|---|---|---|---|---|
| 이름의 출처 | 함수 이름 | 데코레이터 첫 인자 (함수 이름은 _internal_calc) | 함수 이름 | 함수 이름 |
| 설명의 출처 | docstring 한 줄 | description= 인자 | docstring 네 줄 | docstring 전체 (Args:, Returns: 포함) |
| 입력 스키마의 출처 | 타입 힌트 | 타입 힌트 | args_schema=SearchEmployeeInput | 타입 힌트 |
| 인자별 설명 | 없음 | 없음 | description 칸에 있음 | 없음 (설명 글 안에만 있음) |
| "2자 이상" 규칙 | - | - | 스키마의 minLength: 2 | 설명 글의 "(최소 2자)" |
| 규칙을 어기면 | - | - | 본문 전에 ValidationError 예외 | 본문의 if 가 안내 문자열을 반환 |
args_schema.model_json_schema() 에는 title 칸이 보이지만, 모델 호출에 실리는 toolSpec.inputSchema.json 에서는 빠지고 설명은 스키마 밖의 description 칸으로 갑니다. 설치된 langchain-core 1.7.3, langchain-aws 1.9.1 로 변환해 확인한 결과입니다.Args: 는 인자 설명이 되지 않습니다. @tool 의 기본값(parse_docstring=False)에서는 docstring 이 통째로 설명 글이 됩니다. 인자마다 설명과 제약을 스키마에 싣고 싶으면 단계 3처럼 Field(description=..., min_length=...) 를 씁니다.-> int)는 모델에게 가지 않습니다. toolSpec 에는 입력 스키마만 있습니다. 결과가 어떤 모양인지, 실패하면 무엇이 오는지는 단계 3의 docstring 처럼 설명 글에 적어야 모델이 압니다.eval 은 교육용입니다. {"__builtins__": {}} 로 내장 함수를 비웠지만 안전한 격리는 아닙니다. 모델이 만든 문자열이 코드로 실행되는 구조이므로 실제 서비스에서는 수식 파서를 씁니다.tool_error.py 의 4번 갈래는 예외를 삼키고 로그를 남기지 않습니다. 모델에게는 좋지만 운영자에게는 장애가 숨는 구조라, 실제 코드에서는 로그를 따로 남깁니다.day4_practice/tools_basic.py@tool 세 단계(자동 추론 → 이름·설명 명시 → Pydantic args_schema)와 메타데이터 출력. 모델을 부르지 않습니다.day4_practice/tool_error.py입력 오류, 결과 없음, 예상 밖 예외를 모두 안내 문자열로 돌려주는 도구. 모델을 부르지 않습니다.day4_practice/toolnode_parallel.py이 도구들이 Agent 안에서 실행될 때의 모습(ToolNode, handle_tool_errors). 같은 폴더의 ToolNode 플레이어가 다룹니다.