SDK
Tool Tracking
Tool Tracking for the Nora Observability Python SDK
Tool Tracking
Function calling and tool executions are automatically tracked. No decorators or manual instrumentation are required beyond initialization.
Tracked Information:
Tool name
Arguments passed
Return value
Execution time
OpenAI Function Calling
import nora
from openai import OpenAI
import json
nora_client = nora.init(api_key="your-nora-api-key")
client = OpenAI(api_key="your-openai-key")
def get_weather(location, unit="celsius"):
return {
"location": location,
"temperature": 22,
"unit": unit,
"condition": "sunny"
}
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city name, e.g. San Francisco"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
}
]
@nora_client.trace_group(name="weather_query")
def ask_weather(question):
response = client.responses.create(
model="gpt-5",
input=[
{
"role": "user",
"content": question
}
],
tools=tools,
tool_choice="auto"
)
# tool call handling
if response.output and response.output[0]["type"] == "tool_call":
tool_call = response.output[0]
function_name = tool_call["name"]
function_args = json.loads(tool_call["arguments"])
if function_name == "get_weather":
function_response = get_weather(**function_args)
followup = client.responses.create(
model="gpt-5",
input=[
{
"role": "user",
"content": question
},
{
"role": "tool",
"tool_call_id": tool_call["id"],
"content": json.dumps(function_response)
}
]
)
return followup.output_text
return response.output_text
result = ask_weather("What's the weather like in Tokyo?")
print(result)Tool Chain Tracking
import nora
from openai import OpenAI
nora_client = nora.init(api_key="your-nora-api-key")
client = OpenAI(api_key="your-openai-key")
@nora_client.trace(span_type="tool", name="SearchDatabase")
def search_database(query):
return ["Result 1", "Result 2", "Result 3"]
@nora_client.trace(span_type="tool", name="FilterResults")
def filter_results(results, criteria):
return [r for r in results if criteria in r]
@nora_client.trace(span_type="tool", name="RankResults")
def rank_results(results):
return sorted(results, reverse=True)
@nora_client.trace_group(name="search_pipeline")
def search_with_tools(user_query):
results = search_database(user_query)
filtered = filter_results(results, "Result")
ranked = rank_results(filtered)
response = client.responses.create(
model="gpt-5",
input=[
{
"role": "system",
"content": f"Search results: {ranked}"
},
{
"role": "user",
"content": f"Summarize these results for: {user_query}"
}
]
)
return response.output_text
result = search_with_tools("Find information about AI")
print(result)Was this page helpful?