I’m using LangGraph to control the chain behaviour and path.
I have defined 3 functions (get_time, get_content, get_information). The three functions returns the state.
After I convert them using convert to openai function and invoke the graph as following:
def graph_core(state: Graph) -> Graph:
template = get_template()
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI(model='gpt-4o')
graph = prompt | model.bind_functions(functions=[convert_to_openai_function(tool) for tool in tools])
graph_response = graph.invoke(
{
'user_question': state['user_question'],
'time': state['time'],
'content': state['content'],
'information': state['information'],
'chat_history': state['chat_history'],
'response': state['response'],
'messages': state['messages']
})
print(graph_response)
The graph calls only 2 of the three bound tools. Knowing that the template contains keys for the three variables.
This is the router node, invoke tool node, and invoke_tool function.
I even believe that the invoke tool should be implemented like this. I cannot see a difference between using tools as nodes and the implementation of this function.
def should_continue(state: Graph) -> Literal['tool_node', '__end__']:
"""Returns the next node's name to be executed"""
last_message = state['messages']
if name in last_message.additional_kwargs['function_call']:
return 'tool_node'
else:
return '__end__'
def invoke_tool(state: Graph) -> Graph:
last_message = state['messages']
tool_name = last_message.additional_kwargs['function_call']['name']
if tool_name == 'get_time':
if not state['time']:
updated_time = get_time(state)
state['time'] = updated_time['time']
if tool_name == 'get_content':
if not state['content']:
updated_content = get_content(state)
state['content'] = updated_content['content']
if tool_name == 'get_information':
if not state['information']:
updated_information = get_information(state)
state['information'] = updated_information['information']
print('nupdated state in invoke tool')
print(state)
print('n')
return state
def tool_node(state: Graph) -> Graph:
updated_state = invoke_tool(state)
return updated_state
Your guidance is much appreciated!