Function Calling: Building Tool-Using AI Agents
Overview
Section titled “Overview”Function calling allows LLMs to interact with external tools, APIs, and databases, transforming them from text generators into action-taking agents.
Time: 25 minutes
How Function Calling Works
Section titled “How Function Calling Works”- Define available functions
- LLM decides which function to call
- Execute function with LLM-provided arguments
- Return results to LLM
- LLM generates final response
OpenAI Function Calling
Section titled “OpenAI Function Calling”from openai import OpenAIimport json
client = OpenAI()
# Define functionstools = [{ "type": "function", "function": { "name": "get_weather", "description": "Get current weather for a location", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "City name" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] } }, "required": ["location"] } }}]
# Call with functionsresponse = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": "What's the weather in Paris?"}], tools=tools, tool_choice="auto")
# Check if function was calledtool_calls = response.choices[0].message.tool_calls
if tool_calls: for tool_call in tool_calls: function_name = tool_call.function.name function_args = json.loads(tool_call.function.arguments)
# Execute function if function_name == "get_weather": result = get_weather(**function_args)
# Send result back to LLM second_response = client.chat.completions.create( model="gpt-4", messages=[ {"role": "user", "content": "What's the weather in Paris?"}, response.choices[0].message, { "role": "tool", "tool_call_id": tool_call.id, "content": str(result) } ] )
print(second_response.choices[0].message.content)Multi-Tool Agent
Section titled “Multi-Tool Agent”def create_agent_with_tools(): tools = [ { "type": "function", "function": { "name": "search_database", "description": "Search customer database", "parameters": { "type": "object", "properties": { "query": {"type": "string"}, "limit": {"type": "integer"} }, "required": ["query"] } } }, { "type": "function", "function": { "name": "send_email", "description": "Send email to customer", "parameters": { "type": "object", "properties": { "to": {"type": "string"}, "subject": {"type": "string"}, "body": {"type": "string"} }, "required": ["to", "subject", "body"] } } }, { "type": "function", "function": { "name": "calculate", "description": "Perform mathematical calculations", "parameters": { "type": "object", "properties": { "expression": {"type": "string"} }, "required": ["expression"] } } } ]
return tools
# Agent loopdef run_agent(user_message, max_iterations=5): messages = [{"role": "user", "content": user_message}] tools = create_agent_with_tools()
for i in range(max_iterations): response = client.chat.completions.create( model="gpt-4", messages=messages, tools=tools )
message = response.choices[0].message messages.append(message)
# If no tool calls, we're done if not message.tool_calls: return message.content
# Execute each tool call for tool_call in message.tool_calls: function_name = tool_call.function.name function_args = json.loads(tool_call.function.arguments)
# Route to appropriate function result = execute_function(function_name, function_args)
# Add result to messages messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": str(result) })
return "Max iterations reached"LangChain Tools
Section titled “LangChain Tools”from langchain.agents import Tool, AgentExecutor, create_openai_functions_agentfrom langchain_openai import ChatOpenAIfrom langchain.prompts import ChatPromptTemplatefrom langchain_community.tools import DuckDuckGoSearchRun
# Define toolssearch = DuckDuckGoSearchRun()
tools = [ Tool( name="Search", func=search.run, description="Search the internet for current information" ), Tool( name="Calculator", func=lambda x: eval(x), description="Perform calculations" )]
# Create agentllm = ChatOpenAI(model="gpt-4", temperature=0)
prompt = ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant with access to tools."), ("human", "{input}"), ("placeholder", "{agent_scratchpad}")])
agent = create_openai_functions_agent(llm, tools, prompt)agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# Runresult = agent_executor.invoke({"input": "What's 25 * 17 and what's trending on tech news?"})print(result["output"])Best Practices
Section titled “Best Practices”✅ Do:
- Validate function arguments
- Handle errors gracefully
- Set max iterations
- Log function calls
- Implement timeouts
❌ Don’t:
- Allow unbounded loops
- Execute dangerous functions without confirmation
- Ignore error returns
- Skip input validation
Found an issue? Open an issue!