본문 바로가기

LangChain&LangGraph

디버깅 - #1 llm.bind_tools

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을 선택 하거나 선택하지않을 수 있다.

선택을 한 경우 

 

도구 사용 안한 예제

 
tavily_tool = get_tavily_tool()  # 웹검색 tool
tools = [tavily_tool]
# LLM 초기화
llm = get_gemini()
# 도구와 LLM 결합
llm_with_tools = llm.bind_tools(tools)
llm_with_tools.invoke('오늘 날씨 검색')
 

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}})

 

도구 사용 예제

tavily_tool = get_tavily_tool()  # 웹검색 tool
tools = [tavily_tool]
# LLM 초기화
llm = get_gemini()
# 도구와 LLM 결합
llm_with_tools = llm.bind_tools(tools)
llm_with_tools.invoke('오늘 서울 날씨 검색')

 

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 이 스스로 판단하는 부분들이 많이 발생한다. 

그러한 부분을 정확하게 이해하고 디버깅 하기위해서는 위와 같은 기본 내용부터 인지해야 한다 ㅜㅜ