tool 이란
llm이 스스로 판단하여 사용 가능한 도구를 의미한다
도구 생성시 def 로 생성한 메소드에 @tool 데코레이션을 통해 tool로 선언한다
@tool
def get_word_length(word: str) -> int:
"""Returns the length of a word."""
return len(word)
"""Returns the length of a word.""" << "docstring(독스트링)" 에 어떤 상황에서 해당 tool을 사용해야하는지 llm 에게 알려주는 역할 을 수행함
bind_tools 메소드 :
llm 모델에게 다양한 tool을 제공한다.
이후 LLM 에게 질의를 할 경우 LLM 이 판단하여 필요한 tool을 선택 하거나 선택하지않을 수 있다.
선택을 한 경우
도구 사용 안한 예제
AIMessage(content='"오늘 날씨 검색"은 너무 짧습니다. 더 구체적인 검색어를 입력해주세요.', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.5-flash-lite', 'safety_ratings': []}, id='run--018d597e-38ef-4f87-ab22-cef0211ae737-0', usage_metadata={'input_tokens': 89, 'output_tokens': 20, 'total_tokens': 109, 'input_token_details': {'cache_read': 0}})
도구 사용 예제
llm 이 판단하여 웹 도구를 사용하겠다는 결과
AIMessage(content='', additional_kwargs={'function_call': {'name': 'tavily_web_search', 'arguments': '{"query": "\\uc624\\ub298 \\uc11c\\uc6b8 \\ub0a0\\uc528"}'}}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'model_name': 'gemini-2.5-flash-lite', 'safety_ratings': []}, id='run--9d099457-d4c5-4abf-b868-77e642092930-0', tool_calls=[{'name': 'tavily_web_search', 'args': {'query': '오늘 서울 날씨'}, 'id': '66dd1880-af48-4226-959f-abc2bc456480', 'type': 'tool_call'}], usage_metadata={'input_tokens': 90, 'output_tokens': 22, 'total_tokens': 112, 'input_token_details': {'cache_read': 0}})
답변에서 주의깊게 볼 부분은
1. 답변이 AIMessage 객체이다. 객체 임으로 객체.content 등으로 접근해야한다.
2. content가 '' 빈값인 경우 tool을 사용하겠다는 의미로 볼 수 있다.
3. tool_calls 내용을 확인하여 llm 에 툴에게 어떠한 명령을 내린지 확인 가능하다
3.1 name : 여러 도구 중 선택한 도구
3.2 args : 도구에 전달할 key : value ( llm 이 스스로 판단하여 생성)
3.3 id : AIMessages 생성시 답변으로 반드시 Tool_Message가 와야하며 이때 id 가 같은 tool_call_id 로 답변이 와야한다 그렇지 않은경우 에러가 발생할수 있음
4. 때론 무조건 도구를 사용하게 하고싶다면 bind_tools 수행시 tool_choice를 사용하여 강제 할 수 도있다.
log
https://smith.langchain.com/public/4193c44b-f449-4cbb-ae3c-81bbf642aff0/r
LangSmith
smith.langchain.com
LangGraph 개발을 수행하다 보면 기존 프로그래밍보다 디버깅이 어려운 것을 느낄 수 있다.
그 이유는 기존에는 선언적 프로그램을 수행하여 경우의수를 직접 예측이 가능하였다.
하지만 llm을 통한 개발을 수행하다보면 llm 이 스스로 판단하는 부분들이 많이 발생한다.
그러한 부분을 정확하게 이해하고 디버깅 하기위해서는 위와 같은 기본 내용부터 인지해야 한다 ㅜㅜ