> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lab Walkthrough Wire Up Components

> Shows wiring five agent components into a Python script using the OpenAI SDK to build a tool-driven assistant that checks a calendar.

Five components.

That's all an agent needs: a model, tools, memory, a system prompt, and an orchestration loop.

In this lesson we'll wire all five together in a single Python script and observe them working as one. This walkthrough uses the OpenAI Python SDK and demonstrates a simple tool-driven agent that checks a calendar.

## Environment and setup

Prerequisites (already prepared in the environment):

* Python 3.11
* A virtual environment activated
* The OpenAI Python SDK installed ([https://github.com/openai/openai-python](https://github.com/openai/openai-python))
* Working directory: `/root/code`

Create a new file named `agent_components.py` and follow the steps below.

## Overview: the five components

| Component | Role | Example / Where it appears |
| - | - | - |
| Model | The LLM that reasons and decides when to call tools | `model = "openai/gpt-4.1-mini"` |
| Tools | Function definitions the model may request (metadata visible to the model) | `tools = [ { "type": "function", "function": { ... } } ]` |
| Handlers | Your Python functions that actually execute tool logic | `def check_calendar(date):` |
| Memory / Messages | Conversation state shared with the model (system, user, assistant, tool messages) | `messages = [...]` |
| Orchestration loop | Glue that sends messages & tools to the model, executes handlers for tool calls, and feeds results back | the `while True:` loop shown below |

## Step 1 — Skeleton and client initialization

Start with the basic imports and client setup: create an OpenAI client using your API key and base URL from environment variables, select the model, and initialize conversation messages with a system message.

```python theme={null}
from openai import OpenAI
import os
import json

client = OpenAI(
    api_key=os.environ["OPENAI_API_KEY"],
    base_url=os.environ["OPENAI_API_BASE"]
)

model = "openai/gpt-4.1-mini"

messages = [
    {
        "role": "system",
        "content": "You are a helpful personal assistant. Use your tools when you need real data."
    }
]
```

<Callout icon="lightbulb" color="#1CB2FE">
  The system prompt above is component one. It gives the agent an identity and instructs it to use tools rather than guessing when it needs real data.
</Callout>

## Step 2 — Define a tool (and its handler)

Add a `tools` list that describes what the model may call. This is the metadata the model sees. Separately, implement a handler function in Python that executes the requested action and returns the result.

* Tool metadata (name, description, and parameters) is provided to the model.
* Handlers perform the real work and return text results to be appended back into the conversation.

```python theme={null}
tools = [
    {
        "type": "function",
        "function": {
            "name": "check_calendar",
            "description": "Check calendar",
            "parameters": {
                "type": "object",
                "properties": {
                    "date": {"type": "string"}
                },
                "required": ["date"]
            }
        }
    }
]

def check_calendar(date):
    # Example hardcoded calendar items for the provided date
    return "10:00 AM: Team stand-up\n2:00 PM: Dentist"
```

<Callout icon="lightbulb" color="#1CB2FE">
  Remember: the model reads the tool definition (the `tools` list) and may decide to call `check_calendar`. Your code must provide the handler (the `check_calendar` function) to produce the actual result.
</Callout>

## Step 3 — Add a user message

Append a user message that will trigger the agent to use tools as needed.

```python theme={null}
messages.append({"role": "user", "content": "What's on my calendar today?"})
```

## Step 4 — Orchestration loop

The orchestration loop sends messages and `tools` metadata to the model, inspects the model response for tool calls, executes handlers when requested, and feeds the results back to the conversation until the model returns a final answer.

```python theme={null}
while True:
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        tools=tools
    )

    finish_reason = response.choices[0].finish_reason
    msg = response.choices[0].message
    messages.append(msg)

    if finish_reason == "stop":
        # Model has provided a final answer
        print(msg.content)
        break

    if finish_reason == "tool_calls":
        # The model requested one or more tool calls
        for tc in msg.tool_calls:
            name = tc.function.name
            args = json.loads(tc.function.arguments)
            # Call the matching handler in your code
            if name == "check_calendar":
                result = check_calendar(**args)
            else:
                result = f"Unhandled tool: {name}"
            # Append the tool result back into the conversation as a tool message
            messages.append({
                "role": "tool",
                "tool_call_id": tc.id,
                "content": result
            })
```

## Step 5 — Run the script

From the terminal in `/root/code`, run:

```bash theme={null}
python3 agent_components.py
```

What happens:

* The model receives the system prompt and user question.
* Based on the `tools` metadata, the model may decide to call `check_calendar`.
* Your orchestration loop detects the tool call, executes the `check_calendar` handler, and appends the handler output as a tool message.
* The model consumes the tool output and returns a final assistant response that you print.

Expected final output (example):

```text theme={null}
10:00 AM: Team stand-up
2:00 PM: Dentist
```

## Notes and clarifications

* The `tools` list describes the functions the model may call. The model sees the metadata (name, description, and parameter schema) but does not execute code itself.
* Handlers are implemented in your runtime (Python in this example). They can call APIs, access databases, or return simulated responses.
* The orchestration loop is the glue: it passes conversation state and tool definitions to the model, inspects for tool calls, runs handlers, and appends tool output so the model can finish its response.
* For production agents, implement robust error handling, retries, input validation against the declared `parameters` schema, and logging of tool calls and results.

<Callout icon="warning" color="#FF6B6B">
  Keep your API key and base URL secure. Never commit them to source control; prefer environment variables or secrets managers. If keys are exposed, rotate them immediately.
</Callout>

## Quick reference links

* OpenAI Python SDK: [https://github.com/openai/openai-python](https://github.com/openai/openai-python)
* OpenAI API docs: [https://platform.openai.com/docs](https://platform.openai.com/docs)
* Best practices for building tool-enabled agents: see official platform guides and SDK examples

This example demonstrates a minimal, clear pattern for building a tool-enabled Python agent: define what the model can call, implement the handlers, and run an orchestration loop to coordinate model decisions and tool execution.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/ai-agents-for-beginner-openclaw-case-study/module/d77598d4-d1d3-4768-97da-03ead60bf984/lesson/648cbd58-e8d2-40c2-8c8c-27099a2cf39f" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.