[React] agent scratch 부터 만들기
여기에 입력하면 된다.
개요
Langgraph 를 사용하여 처음부터 ReAct 에이전트를 구현하는 방법을 적도록 하겠다.
Graph 상태 정의
1
2
3
4
5
6
7
8
from typing import Annotated, Sequence, TypedDict
from langchain_core.messages import BaseMessage
from langgraph.graph.message import add_messages
class AgentState(TypedDict):
"""The state of the agent"""
## add_messags is a reducer
messages: Annotated[Sequence[BaseMessage], add_messages]
Tools 정의
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from langchain_core.tools import tool
@tool
def get_weather(location: str):
"""Call to get the weather from a specific location."""
# This is a placeholder for the actual implementation
# Don't let the LLM know this though 😊
if any([city in location.lower() for city in ["sf", "san francisco"]]):
return "It's sunny in San Francisco, but you better look out if you're a Gemini 😈."
else:
return f"I am not sure what the weather is in {location}"
tools = [get_weather]
model = model.bind_tools(tools)
Node , Edge 정의
기본 ReAct 에이전트는 모델을 호출하는 노드와 툴을 사용하는 노드, 이렇게 두 개의 노드만 포함한다. 하지만 이 구조는 사용 사례에 따라 수정 가능하다.
예: 구조화된 출력을 추가하는 노드, 외부 작업(이메일 보내기, 캘린더 이벤트 추가 등)을 실행하는 노드 등을 추가하거나, 모델 호출 방식 및 툴 호출 여부를 판단하는 조건 등을 커스터마이징 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import json
from langchain_core.messages import ToolMessage, SystemMessage
from langchain_core.runnables import RunnableConfig
tools_by_name = {tool.name: tool for tool in tools}
# Define our tool node
def tool_node(state:AgentState):
outputs = []
for tool_call in state['messages'][-1].tool_calls:
tool_result = tools_by_name[tool_call['name']].invoke(tool_call['args'])
outputs.append(
ToolMessage(
content=json.dumps(tool_result),
name=tool_call['name'],
tool_call_id=tool_call['id']
)
)
return {'messages' : outputs}
# Define the node that calls the model
def call_model(
state: AgentState,
config: RunnableConfig,
):
system_prompt = SystemMessage(
"You are a helpful AI assistant, please respond to the users query to the best of your ability!"
)
response = model.invoke([system_prompt] + state['messages'] , config)
return {'messages' : [response]}
# Define the conditional edge that determines wheter to continue or not
def should_continue(state:AgentState):
messages = state['messages']
last_message = messages[-1]
if not last_message.tool_calls:
return "end"
else:
return "continue"
Graph 정의
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from langgraph.graph import StateGraph, END
workflow = StateGraph(AgentState)
workflow.add_node('agent', call_model)
workflow.add_node('tools', tool_node)
workflow.set_entry_point('agent')
workflow.add_conditional_edges(
'agent',
should_continue,
{
'continue': 'tools',
'end' : END
}
)
workflow.add_edge('tools','agent')
graph = workflow.compile()
ReAct 에이전트 사용하기
1
2
3
4
5
6
7
8
9
10
11
# Helper function for formatting the stream nicely
def print_stream(stream):
for s in stream:
message = s["messages"][-1]
if isinstance(message, tuple):
print(message)
else:
message.pretty_print()
inputs = {"messages": [("user", "what is the weather in sf")]}
print_stream(graph.stream(inputs, stream_mode="values"))
1
2
3
4
5
6
7
8
================================ Human Message =================================
what is the weather in sf
================================== Ai Message ================================== Tool Calls: get_weather (call_6f7py2q8) Call ID: call_6f7py2q8 Args: location: sf
================================= Tool Message ================================= Name: get_weather "It's sunny in San Francisco, but you better look out if you're a Gemini \ud83d\ude08."
================================== Ai Message ================================== It's sunny in San Francisco, but you better look out if you're a Gemini \ud83d\ude08. Is there anything else you would like to know about the weather?
Reference
Google AdSense — Post Ad
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

Comments powered by Disqus.