ExamplescriptbeginnerRunnableresearch-brief
Retrieval
Runnable example (beginner) for script using openai, pydantic.
Key Facts
- Level
- beginner
- Runtime
- Python • OpenAI API
- Pattern
- Context-backed research with explicit evidence
- Interaction
- Live sandbox • Script
- Updated
- 14 March 2026
Navigate this example
Library
Browse examplesReopen the wider library to compare adjacent patterns and linked learning paths.Interaction
Run sandbox nowTry the interaction directly in this example’s guided sandbox surface.Source
Open full sourceRead the real implementation, highlighted checkpoints, and runtime requirements.MCP
Call via MCPUse the same resource inside agents, deterministic exports, and MCP setup flows.
Linked principles
4-retrieval.py
python
import json
import os
from openai import OpenAI
from pydantic import BaseModel, Field
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
"""
docs: https://platform.openai.com/docs/guides/function-calling
"""
# --------------------------------------------------------------
# Define the knowledge base retrieval tool
# --------------------------------------------------------------
def search_kb(question: str):
"""
Load the whole knowledge base from the JSON file.
(This is a mock function for demonstration purposes, we don't search)
"""
with open("kb.json", "r") as f:
return json.load(f)
# --------------------------------------------------------------
# Step 1: Call model with search_kb tool defined
# --------------------------------------------------------------
tools = [
{
"type": "function",
"function": {
"name": "search_kb",
"description": "Get the answer to the user's question from the knowledge base.",
"parameters": {
"type": "object",
"properties": {
"question": {"type": "string"},
},
"required": ["question"],
"additionalProperties": False,
},
"strict": True,
},
}
]
system_prompt = "You are a helpful assistant that answers questions from the knowledge base about our e-commerce store."
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "What is the return policy?"},
]
completion = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
)
# --------------------------------------------------------------
# Step 2: Model decides to call function(s)
# --------------------------------------------------------------
completion.model_dump()
# --------------------------------------------------------------
# Step 3: Execute search_kb function
# --------------------------------------------------------------
def call_function(name, args):
if name == "search_kb":
return search_kb(**args)
for tool_call in completion.choices[0].message.tool_calls:
name = tool_call.function.name
args = json.loads(tool_call.function.arguments)
messages.append(completion.choices[0].message)
result = call_function(name, args)
messages.append(
{"role": "tool", "tool_call_id": tool_call.id, "content": json.dumps(result)}
)
# --------------------------------------------------------------
# Step 4: Supply result and call model again
# --------------------------------------------------------------
class KBResponse(BaseModel):
answer: str = Field(description="The answer to the user's question.")
source: int = Field(description="The record id of the answer.")
completion_2 = client.beta.chat.completions.parse(
model="gpt-4o",
messages=messages,
tools=tools,
response_format=KBResponse,
)
# --------------------------------------------------------------
# Step 5: Check model response
# --------------------------------------------------------------
final_response = completion_2.choices[0].message.parsed
final_response.answer
final_response.source
# --------------------------------------------------------------
# Question that doesn't trigger the tool
# --------------------------------------------------------------
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "What is the weather in Tokyo?"},
]
completion_3 = client.beta.chat.completions.parse(
model="gpt-4o",
messages=messages,
tools=tools,
)
completion_3.choices[0].message.content
Related principles
- P1delegationDesign for delegation rather than direct manipulationDesign experiences around the assignment of work, the expression of intent, the setting of constraints, and the review of results, rather than requiring users to execute each step manually.Open principle →
- P8trustMake hand-offs, approvals, and blockers explicitWhen the system cannot proceed, the reason should be immediately visible, along with any action required from the user or another dependency.Open principle →
- P9orchestrationRepresent delegated work as a system, not merely as a conversationWhere work involves multiple steps, agents, dependencies, or concurrent activities, it should be represented as a structured system rather than solely as a message stream.Open principle →
- P10delegationOptimise for steering, not only initiatingThe system should support users not only in starting tasks, but also in guiding, refining, reprioritising, and correcting work while it is underway.Open principle →