langgraph icon indicating copy to clipboard operation
langgraph copied to clipboard

OpenAI Agent Not Function Calling

Open jasonngap1 opened this issue 9 months ago • 1 comments

Checked other resources

  • [X] I added a very descriptive title to this issue.
  • [X] I searched the LangChain documentation with the integrated search.
  • [X] I used the GitHub search to find a similar question and didn't find it.
  • [X] I am sure that this is a bug in LangChain rather than my code.

Example Code

def call_model(state):
    messages = state['messages']
    response = model.invoke(messages)
    # We return a list, because this will get added to the existing list
    return {"messages": [response]}

# Define the function to execute tools
def call_tool(state):
    messages = state['messages']
    # Based on the continue condition
    # we know the last message involves a function call
    last_message = messages[-1]
    # We construct an ToolInvocation from the function_call
    action = ToolInvocation(
        tool=last_message.additional_kwargs["function_call"]["name"],
        tool_input=json.loads(last_message.additional_kwargs["function_call"]["arguments"]),
    )
    # We call the tool_executor and get back a response
    response = tool_exec.invoke(action)
    # We use the response to create a FunctionMessage
    function_message = FunctionMessage(content=str(response), name=action.tool)
    # We return a list, because this will get added to the existing list
    return {"messages": [function_message]}

class RetrieverAgent():
    def __init__(self) -> None:
        self.workflow = StateGraph(AgentState)
    
        # Define the two nodes we will cycle between
        self.workflow.add_node("agent", call_model)
        self.workflow.add_node("action", call_tool)

        # Set the entrypoint as `agent`
        # This means that this node is the first one called
        self.workflow.set_entry_point("agent")

        self.workflow.add_edge("agent", "action")
        self.workflow.add_conditional_edges(
            "action",
            should_end,
            {
                "continue": "agent",
                "end": END
            }
        )
        
        self.app = self.workflow.compile()
    
    def run(self, human_input):
        inputs = {"messages": [HumanMessage(content=human_input)]}
        
        with get_openai_callback() as cb:
            result = self.app.invoke(inputs)

        return result['messages'][-1].content
    
agent = RetrieverAgent()

Error Message and Stack Trace (if applicable)

tool=last_message.additional_kwargs["function_call"]["name"],\n\n\nKeyError: 'function_call'"

Description

  • I am trying to create an agent that has to call single or multiple tools based on the user query
  • the first step of the agent has to be function calling
  • currently, based on certain user queries that isn't very clear, the agent will not do function calling and instead generate an answer

System Info

langchain==0.1.17 langgraph==0.0.40

jasonngap1 avatar May 01 '24 02:05 jasonngap1

I don't see any llm in the code you've shared but I'm guessing it's one of two things:

  1. You are using tool calling instead of function calling. This is in fact recommended, and we just updated the docs to migrate to reflect this here. The tool arguments are in last_message.tool_calls[0]['args']
  2. Your router / conditional edge condition is incorrect. The tool node shouldn't be active if no tools/function calls are made by the LLM. It seems like you are still going to that node inappropriately

hinthornw avatar May 04 '24 19:05 hinthornw

Feel free to re-open if this is still an issue!

hinthornw avatar May 07 '24 06:05 hinthornw

same issue, how to resolve?

sorokinvld avatar May 30 '24 21:05 sorokinvld