2025, Oct 16 11:31

OpenAI Agents और Ollama में typing.Union TypeError: कारण और समाधान

OpenAI Agents को Ollama से जोड़ते समय होने वाला TypeError: Cannot instantiate typing.Union क्यों आता है और openai को 1.99.0 से नीचे पिन करके इसे कैसे ठीक करें.

Ollama बैकएंड से जुड़े OpenAI Agents SDK के साथ फ़ंक्शन कॉल कभी‑कभी अनपेक्षित रूप से टूट जाते हैं—कारण होता है typing.Union से उठने वाला TypeError. अगर आपका एजेंट किसी साधारण टूल कॉल पर ही क्रैश हो जाए और ट्रेसबैक “TypeError: Cannot instantiate typing.Union” पर खत्म हो, तो मुमकिन है कि आप agents कोड और नवीनतम openai पैकेज के बीच संगतता (compatibility) की खाई से टकरा रहे हैं।

ऐसा न्यूनतम सेटअप जो क्रैश दोहराता है

नीचे दिया गया प्रोग्राम OpenAIChatCompletionsModel को Ollama के HTTP endpoint से जोड़ता है और एक छोटा फ़ंक्शन‑टूल उपलब्ध कराता है। तर्क साफ है: क्लाइंट बनाएं, टूल पंजीकृत करें, और एजेंट से 2 + 2 निकालने को कहें।

from dotenv import load_dotenv
from agents import Agent, Runner, AsyncOpenAI, OpenAIChatCompletionsModel, function_tool
import asyncio
load_dotenv(override=True)
host_url = "http://localhost:11434/v1"
api_token = "dummy"
model_id = "qwen3:4b"
@function_tool
def add_numbers(x: int, y: int) -> int:
    """Send two integers and return their sum"""
    print(f"Adding {x} and {y}")
    return x + y
async def entrypoint():
    async_client = AsyncOpenAI(base_url=host_url, api_key=api_token)
    chat_model = OpenAIChatCompletionsModel(model=model_id, openai_client=async_client)
    base_agent = Agent(
        name="basic_worker",
        instructions="You are a simple agent that can perform basic tasks",
        tools=[add_numbers],
        model=chat_model,
    )
    result = await Runner.run(base_agent, "What is 2 + 2?")
    print(result)
asyncio.run(entrypoint())

प्रभावित सेटअप पर यह इस ट्रेसबैक के साथ असफल होता है, जो यहाँ आकर रुकता है:

TypeError: Cannot instantiate typing.Union

असल में क्या टूट रहा है और क्यों

नाकामी इस बात से आती है कि agents का कोड टूल‑कॉल संदेश कैसे बनाता है। अंदरखाते यह इस तरह ChatCompletionMessageToolCallParam तैयार करता है:

new_tool_call = ChatCompletionMessageToolCallParam(
    id=fs["id"],
    type="function",
    function={
        "name": "file_search_call",
        "arguments": json.dumps({
            "queries": fs.get("queries", []),
            "status": fs.get("status"),
        }),
    },
)

लेकिन ChatCompletionMessageToolCallParam दरअसल दो pydantic मॉडलों के Union का एक टाइप उर्फ़ (type alias) है:

ChatCompletionMessageToolCallParam: TypeAlias = Union[
    ChatCompletionMessageFunctionToolCallParam,
    ChatCompletionMessageCustomToolCallParam,
]

Python में typing.Union को किसी क्लास की तरह instantiate करना मान्य नहीं है। Union कोई ठोस टाइप नहीं है जिसे आप कॉल कर सकें; यह सिर्फ़ एक टाइप अभिव्यक्ति है जो बताती है कि मान कई टाइपों में से किसी एक का हो सकता है। यह क्यों फटता है, देखने के लिए अलग से वही गलत इस्तेमाल देखें:

from typing import Union
UType = Union[int, str]
UType("hello")

यह हर बार यह त्रुटि उठाता है:

TypeError: Cannot instantiate typing.Union

संक्षेप में, ChatCompletionMessageToolCallParam को इस तरह बनाने वाला agents मॉड्यूल‑पथ नवीनतम openai पैकेज के साथ सही नहीं बैठता। यह असंगति upstream में दर्ज है और इसे संस्करण से जुड़ी समस्या के रूप में पुष्टि मिली है।

समाधान

openai पैकेज को 1.99.0 से कम संस्करण पर पिन करें। लिंक किए गए इशू के अनुसार, डाउनग्रेड करने से यह त्रुटि दूर हो जाती है।

यदि आप निर्भरताएँ constraints फ़ाइल या इसी तरह की व्यवस्था से संभालते हैं, तो स्पेसिफ़िकेशन को यूँ बदलें:

openai<1.99.0
openai-agents>=0.0.15

एप्लिकेशन कोड में किसी बदलाव की ज़रूरत नहीं; openai का संस्करण सीमित करते ही एजेंट का टूल‑कॉल पथ Union को instantiate करने की कोशिश छोड़ देता है और प्रवाह सामान्य रूप से आगे बढ़ता है।

निर्भरता समायोजित करने के बाद कार्यरत कोड

openai<1.99.0 इंस्टॉल होने पर यही प्रोग्राम सफलतापूर्वक चलता है:

from dotenv import load_dotenv
from agents import Agent, Runner, AsyncOpenAI, OpenAIChatCompletionsModel, function_tool
import asyncio
load_dotenv(override=True)
host_url = "http://localhost:11434/v1"
api_token = "dummy"
model_id = "qwen3:4b"
@function_tool
def add_numbers(x: int, y: int) -> int:
    """Send two integers and return their sum"""
    print(f"Adding {x} and {y}")
    return x + y
async def entrypoint():
    async_client = AsyncOpenAI(base_url=host_url, api_key=api_token)
    chat_model = OpenAIChatCompletionsModel(model=model_id, openai_client=async_client)
    base_agent = Agent(
        name="basic_worker",
        instructions="You are a simple agent that can perform basic tasks",
        tools=[add_numbers],
        model=chat_model,
    )
    result = await Runner.run(base_agent, "What is 2 + 2?")
    print(result)
asyncio.run(entrypoint())

आपकी स्टैक के लिए यह क्यों मायने रखता है

टाइप्ड SDK तेज़ी से बदलते हैं, और मॉडल परिभाषाओं में छोटे‑मोटे फेरबदल ऊपरी स्तर के रैपर्स की धारणाओं को गलत साबित कर सकते हैं। यहाँ openai पैकेज का Union‑आधारित type alias उस कोड से टकराता है जो उसे ठोस क्लास मानकर उपयोग करता है। संस्करण‑संगतता पर नज़र रखना प्रोडक्शन में मुश्किल‑से‑डीबग क्रैश को रोकता है—खासकर तब, जब आप OpenAI Agents SDK और Ollama बैकएंड जैसे कई लेयरों को जोड़ रहे हों।

सार

यदि आपका OpenAI Agents + Ollama इंटीग्रेशन “Cannot instantiate typing.Union” के साथ फेल हो रहा है, तो तत्काल और परखा हुआ इलाज है: openai-agents≥0.0.15 के साथ openai को 1.99.0 से कम संस्करण पर पिन करें। इससे Union को गलत तरीके से instantiate करने वाली राह हट जाती है और फ़ंक्शन कॉल हैंडलिंग पटरी पर आ जाती है। जब upstream में यह असंगति सुलझ जाए, तो चर्चा पर नज़र रखें और मॉड्यूल्स के संरेखित होते ही पिन पर पुनर्विचार करें।

यह लेख StackOverflow पर प्रश्न (लेखक: Dileep17) और Tom McLean के उत्तर पर आधारित है।