반응형

🏁 학습할 내용
- 랭체인 tool 활용
- 랭그래프에서 tool 제공
⛓️ LangChain tool 제공
1️⃣ tool 만들기
랭체인에서 tool은 schema를 가진 함수다.
- @tool 데코레이
- 설명
- 파라미터 및 리턴 타입
from langchain_core.tools import tool
@tool
def add(a: int, b: int) -> int:
"""숫자 a와 b를 더합니다."""
return a + b
@tool
def multiply(a: int, b: int) -> int:
"""숫자 a와 b를 곱합니다."""
return a * b
2️⃣ llm에 바인딩
small_llm = AzureChatOpenAI(
azure_deployment='gpt-4o-mini-2024-07-18',
api_version='2024-08-01-preview',
)
llm_with_tools = small_llm.bind_tools([add, multiply])
3️⃣ 메시지 리스트(시퀀스) 던져주기
- 왜 리스트를 던져 줘야하나 ?
- llm에게 단순 질문을 던져주는 것보다 다음과 같이 던져주는게좋음
- 질문 -> 휴면 메시지
- AI메시지
- 도구가 필요한지 안한지, 결정 후, 도구가 필요하면 AI메시지 안에있는 tool_calls에 bind한 도구 중 필요한게 전달됨
- Tool메시지
- 해당 Tool을 쓴 결과
from typing import Sequence
from langchain_core.messages import AnyMessage, HumanMessage
human_message = HumanMessage(query) # 3 곱하기 5는
message_list: Sequence[AnyMessage] = [human_message]
ai_message = llm_with_tools.invoke(message_list) # AI 메시지
message_list.append(ai_message)
tool_message = multiply.invoke(ai_message.tool_calls[0]) #Tool 메시지
message_list.append(tool_message)
llm_with_tools.invoke(message_list) # Tool이 있는 LLM 호출
⚓ LangGraph에서 tool 제공
위 내용에서 크게 바뀌는 부부만 살펴보자.
- message_list -> MessagesState
- append를 일일히 하지 않아도 됨
- MessagesState는 add_messages로 자동으로 추가됨
class MessagesState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
- ToolNode 이용
- tool을 그래프의 노드로 치환 시킴
- Tool 노드는 아래 제약조건을 반드시 지켜야한다.
- 메시지의 배열을 포함해야한다.
- AnyMessage
- SystemMessage
- AIMessage
- HumanMessage
- ToolMessage
- AnyMessage
- 마지막 메시지는 반드시 AIMessage여야한다.
- AIMessage는 반드시 tool_calls(선택된 tool) 있어야한다.
- 메시지의 배열을 포함해야한다.
from langgraph.prebuilt import ToolNode
tool_list = [add, multiply]
llm_with_tools = small_llm.bind_tools(tool_list) # LLM에 tool 바인딩
tool_node = ToolNode(tool_list) # ToolNode 생성
from langgraph.prebuilt import ToolNode
tool_list = [add, multiply]
llm_with_tools = small_llm.bind_tools(tool_list)
tool_node = ToolNode(tool_list)
from langgraph.graph import MessagesState, StateGraph
graph_builder = StateGraph(MessagesState)
# %%
def agent(state: MessagesState) -> MessagesState:
"""
에이전트 함수는 주어진 상태에서 메시지를 가져와
LLM과 도구를 사용하여 응답 메시지를 생성합니다.
Args:
state (MessagesState): 메시지 상태를 포함하는 state.
Returns:
MessagesState: 응답 메시지를 포함하는 새로운 state.
"""
# 상태에서 메시지를 추출합니다.
messages = state['messages']
# LLM과 도구를 사용하여 메시지를 처리하고 응답을 생성합니다.
response = llm_with_tools.invoke(messages)
# 응답 메시지를 새로운 상태로 반환합니다.
return {'messages': [response]}
# %%
from typing import Literal
from langgraph.graph import END
def should_continue(state: MessagesState) -> Literal['tools', END]:
"""
주어진 메시지 상태를 기반으로 에이전트가 계속 진행할지 여부를 결정합니다.
Args:
state (MessagesState): `state`를 포함하는 객체.
Returns:
Literal['tools', END]: 도구를 사용해야 하면 `tools`를 리턴하고,
답변할 준비가 되었다면 END를 반환해서 프로세스를 종료합니다.
"""
# 상태에서 메시지를 추출합니다.
messages = state['messages']
# 마지막 AI 메시지를 가져옵니다.
last_ai_message = messages[-1]
# 마지막 AI 메시지가 도구 호출을 포함하고 있는지 확인합니다.
if last_ai_message.tool_calls:
# 도구 호출이 있으면 'tools'를 반환합니다.
return 'tools'
# 도구 호출이 없으면 END를 반환하여 프로세스를 종료합니다.
return END
출처
반응형
'AI > LangGraph' 카테고리의 다른 글
| 히스토리 관리 (0) | 2026.02.26 |
|---|---|
| 지금까지 우리가 만든건 Agent가 아니다?? (0) | 2026.02.23 |
| RunnablePassthrough (0) | 2026.02.23 |
| SubGraph와 Router (0) | 2026.02.22 |
| Corrective RAG (0) | 2026.02.22 |