Tool Calling Architecture
Tool Execution Flow:
Intent Recognition → Tool Selection → Parameter Extraction → Execution → Result Integration
Intent Recognition → Tool Selection → Parameter Extraction → Execution → Result Integration
Analyze
Select
Execute
Integrate
Key Components:
- Tool Registry and Discovery
- Parameter Validation and Mapping
- Execution Engine and Error Handling
- Result Processing and Integration
Tool Implementation Example
from langchain.tools import BaseTool
from typing import Optional, Type
from pydantic import BaseModel, Field
class CalculatorInput(BaseModel):
expression: str = Field(description="Mathematical expression to evaluate")
class CalculatorTool(BaseTool):
name = "calculator"
description = "Useful for mathematical calculations"
args_schema: Type[BaseModel] = CalculatorInput
def _run(self, expression: str) -> str:
try:
# Safe evaluation of mathematical expressions
result = eval(expression, {"__builtins__": {}}, {})
return f"Result: {result}"
except Exception as e:
return f"Error: {str(e)}"
async def _arun(self, expression: str) -> str:
return self._run(expression)
class DatabaseQueryTool(BaseTool):
name = "database_query"
description = "Query database for information"
def __init__(self, connection_string: str):
super().__init__()
self.db = Database(connection_string)
def _run(self, query: str) -> str:
try:
# Validate query for safety
if not self.is_safe_query(query):
return "Error: Unsafe query detected"
results = self.db.execute(query)
return self.format_results(results)
except Exception as e:
return f"Database error: {str(e)}"
def is_safe_query(self, query: str) -> bool:
# Implement query validation logic
forbidden_keywords = ['DROP', 'DELETE', 'UPDATE', 'INSERT']
return not any(keyword in query.upper() for keyword in forbidden_keywords)
class APICallTool(BaseTool):
name = "api_call"
description = "Make HTTP API calls to external services"
def __init__(self, base_url: str, api_key: str):
super().__init__()
self.base_url = base_url
self.api_key = api_key
self.session = requests.Session()
self.session.headers.update({"Authorization": f"Bearer {api_key}"})
def _run(self, endpoint: str, method: str = "GET", data: dict = None) -> str:
try:
url = f"{self.base_url}/{endpoint}"
# Rate limiting
if not self.check_rate_limit():
return "Error: Rate limit exceeded"
response = self.session.request(method, url, json=data)
response.raise_for_status()
return json.dumps(response.json(), indent=2)
except Exception as e:
return f"API error: {str(e)}"
def check_rate_limit(self) -> bool:
# Implement rate limiting logic
return True
# Tool orchestration with LangChain
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_openai import ChatOpenAI
def create_agent_with_tools():
# Initialize LLM
llm = ChatOpenAI(model="gpt-4", temperature=0)
# Create tools
tools = [
CalculatorTool(),
DatabaseQueryTool("postgresql://localhost/mydb"),
APICallTool("https://api.example.com", "your-api-key"),
# Add more tools as needed
]
# Create agent
agent = create_tool_calling_agent(llm, tools, prompt_template)
# Create executor with error handling
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
max_iterations=10,
handle_parsing_errors=True
)
return agent_executor
# Usage example
agent = create_agent_with_tools()
result = agent.invoke({
"input": "Calculate the square root of 144 and then query the database for users with that ID"
})