카테고리 없음

OPEN AI SDK - Customer support agent(4)- tools

hyunsoo CHUNG 2026. 1. 1. 21:02

Tool System Integration Explanation

1. Tool Definition - @function_tool Decorator

@function_tool
def run_diagnostic_check(
    context: UserAccountContext, product_name: str, issue_description: str
) -> str:
    """
    Run a diagnostic check on the customer's product to identify potential issues.

    Args:
        product_name: Name of the product experiencing issues
        issue_description: Description of the problem
    """
    diagnostics = [
        "✅ Server connectivity: Normal",
        "✅ API endpoints: Responsive",
        "⚠️  Cache memory: 85% full (recommend clearing)",
        "✅ Database connections: Stable",
        "⚠️  Last update: 7 days ago (update available)",
    ]

    return f"🔍 Diagnostic results for {product_name}:\n" + "\n".join(diagnostics)
  • @function_tool: A decorator that registers a function as a tool.
  • Key Features:
    • The first parameter is context: UserAccountContext (automatically injected).
    • The remaining parameters are provided by the LLM.
    • The Docstring is used as the tool description.
    • The return value is a string.

2. How the LLM Understands Tools

A. Tool Schema Generation The @function_tool decorator analyzes the function to generate a schema that the LLM can understand:

# Function Definition
@function_tool
def lookup_order_status(context: UserAccountContext, order_number: str) -> str:
    """
    Look up the current status and details of an order.
    Args:
        order_number: Customer's order number
    """

Generated Tool Schema (Internally):

 
{
  "name": "lookup_order_status",
  "description": "Look up the current status and details of an order.",
  "parameters": {
    "type": "object",
    "properties": {
      "order_number": {
        "type": "string",
        "description": "Customer's order number"
      }
    },
    "required": ["order_number"]
  }
}

B. Providing the Tool List

order_agent = Agent(
    name="Order Management Agent",
    instructions=dynamic_order_agent_instructions,
    tools=[
        lookup_order_status,
        initiate_return_process,
        schedule_redelivery,
        expedite_shipping,
    ],
    hooks=AgentToolUsageLoggingHooks(),
)
  • tools: A list of tools available to the agent.
  • The Runner generates a schema for each tool and provides it to the LLM.
  • The LLM selects a tool by referencing this list and schema.

3. Context Automatic Injection Mechanism

A. Context Delivery Path

            stream = Runner.run_streamed(
                st.session_state["agent"],
                message,
                session=session,
                context=user_account_ctx,
            )
  • Pass context=user_account_ctx to Runner.run_streamed().
  • The Runner internally wraps and manages it using RunContextWrapper.

B. Context Injection During Tool Calls

@function_tool
def lookup_order_status(context: UserAccountContext, order_number: str) -> str:
    """
    Look up the current status and details of an order.

    Args:
        order_number: Customer's order number
    """
    statuses = ["processing", "shipped", "in_transit", "delivered"]
    # ... implementation details ...
    return f"""
📦 Order Status: {order_number}
📍 Shipping to: {context.email}
    """.strip()
  • If the first parameter is of type UserAccountContext, the Runner automatically injects it.
  • The LLM does not provide the context parameter.
  • Inside the tool, properties like context.email, context.customer_id, context.tier, etc., can be used.

4. Parameter Generation Process by LLM

A. User Request Analysis

User: "Check the status of order number ORD-123"

B. Tool Selection

LLM Analysis:

  • Request: "Check order status"
  • Check available tools: lookup_order_status, initiate_return_process, etc.
  • Selection: lookup_order_status

C. Tool Schema Analysis

LLM Checks Schema for lookup_order_status:

  • name: "lookup_order_status"
  • description: "Look up the current status and details of an order."
  • parameters: order_number (string, required)
  • context is ignored as it is automatically injected.

D. Parameter Extraction

LLM Extracts Parameters from Request: "Check the status of order number ORD-123" → order_number="ORD-123"

E. Tool Call Generation

LLM Generates Tool Call:

JSON
 
{
  "tool_name": "lookup_order_status",
  "parameters": {
    "order_number": "ORD-123"
  }
}

5. Full Tool Execution Flow

[Step 1] User Request
   User: "Check the status of order number ORD-123"
   ↓
[Step 2] Call Runner.run_streamed()
   Runner.run_streamed(
       order_agent,
       "...",
       context=user_account_ctx  ← Context Passed
   )
   ↓
[Step 3] Runner Generates Tool Schema
   Runner checks order_agent.tools list
   → Analyzes @function_tool decorators
   → Prepares tool list for LLM
   ↓
[Step 4] Order Agent's LLM Execution
   Information provided to LLM:
   - Instructions, Tools (Schema), Request, History
   ↓
[Step 5] LLM Selects Tool & Extracts Parameters
   - Tool: lookup_order_status
   - Parameter: order_number="ORD-123"
   ↓
[Step 6] LLM Generates Tool Call
   Output: { "function": { "name": "lookup_order_status", ... } }
   ↓
[Step 7] on_tool_start Hook Called
   Displays "🔧 Order Management Agent starting tool..." in sidebar
   ↓
[Step 8] Runner Executes Tool
   Runner calls function:
   lookup_order_status(
       context=wrapper.context,  ← Auto Injected
       order_number="ORD-123"    ← Provided by LLM
   )
   ↓
[Step 9] Tool Function Logic Execution
   Inside lookup_order_status():
   - Use context.email, context.tier
   - Query order logic
   - Return result string
   ↓
[Step 10] on_tool_end Hook Called
   Displays tool result in sidebar
   ↓
[Step 11] LLM Delivers Result to User
   LLM receives tool result → Converts to friendly message
   → "Order ORD-123 is currently in transit..."

6. Handling Parameter Types

def lookup_order_status(context: UserAccountContext, order_number: str) -> str:
  • No default value → Required.
  • The LLM must extract this from the user request. If missing, it asks the user.

B. Optional Parameters (Default Values)

def lookup_billing_history(context: UserAccountContext, months_back: int = 6) -> str:
  • Default value = 6 exists → Optional.
  • If the LLM cannot extract it, the default value is used.

C. Multiple Parameters

 
def initiate_return_process(..., order_number: str, return_reason: str, items: str) -> str:
  • Extract multiple parameters from the user request.
  • The LLM maps each parameter accordingly.

7. Context Usage Examples

A. Reading Info from Context

📍 Shipping to: {context.email}
  • context.email: Customer Email
  • context.customer_id: Customer ID
  • context.tier: Customer Tier

B. Context-based Conditional Logic

processing_days = 3 if context.is_premium_customer() else 5
  • context.is_premium_customer(): Check if premium.
  • Premium customers get faster processing (3 days vs 5 days).

C. Context-based Access Control

if not context.is_premium_customer():
    return "❌ Expedited shipping upgrade requires Premium membership"
  • Feature available only to premium customers.
  • Check permissions via Context.

8. Tool Usage Logging - AgentHooks

class AgentToolUsageLoggingHooks(AgentHooks):
    async def on_tool_start(self, ...):
        # ... Log tool start ...

    async def on_tool_end(self, ...):
        # ... Log tool result ...

    async def on_handoff(self, ...):
        # ... Log handoff ...
  • AgentHooks: Lifecycle event hooks for the agent.
  • Major Methods:
    • on_tool_start: Called when a tool starts execution.
    • on_tool_end: Called when a tool completes execution (includes result).
    • on_handoff: Called when a handoff occurs.
    • on_start / on_end: Agent activation/completion.

9. Key Concepts Summary

Concept Description
@function_tool Decorator that registers a function as a tool.
context UserAccountContext automatically injected as the first parameter.
Tool Schema Metadata generated for the tool so the LLM can understand it.
tools List of tools to register with the agent.
AgentHooks Class that handles agent lifecycle events.
on_tool_start Hook called when tool execution begins.
on_tool_end Hook called when tool execution completes.

10. Full System Diagram

┌─────────────────────────────────────────┐
│  User Request                           │
│  "Check the status of order ORD-123"    │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  Runner.run_streamed(order_agent, ...)  │
│  Pass context=user_account_ctx          │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  Runner Generates Tool Schema           │
│  - Analyze @function_tool decorator     │
│  - Parse function signature             │
│  - Parse Docstring                      │
│  - Generate JSON Schema                 │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  Provide Tool Info to LLM               │
│  - Agent instructions                   │
│  - Tool List (with Schema)              │
│  - User Request                         │
│  - Conversation History                 │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  LLM Selects Tool & Extracts Params     │
│  - Analyze User Request                 │
│  - Select appropriate Tool              │
│  - Check Tool Schema                    │
│  - Extract: order_number="ORD-123"      │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  LLM Generates Tool Call                │
│  {                                      │
│    "tool_calls": [{                     │
│      "function": {                      │
│        "name": "lookup_order_status",   │
│        "arguments": "{\"order_number\": \"ORD-123\"}" │
│      }                                  │
│    }]                                   │
│  }                                      │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  Call on_tool_start Hook                │
│  - Display tool start in sidebar        │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  Runner Executes Tool                   │
│  lookup_order_status(                   │
│    context=wrapper.context,  ← Auto     │
│    order_number="ORD-123"    ← From LLM │
│  )                                      │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  Tool Function Execution                │
│  - Use context.email, id, tier          │
│  - Query order status                   │
│  - Return result string                 │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  Call on_tool_end Hook                  │
│  - Display tool result in sidebar       │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  LLM Delivers Result to User            │
│  "Order ORD-123 is currently..."        │
└─────────────────────────────────────────┘