OpenAI Special Usage
Deprecation Notice
Anthropic 已弃用 thinking.type: "enabled" 方式。Claude 4.7+ 模型已完全不支持此参数,4.6 系列也已标记为弃用。新调用请使用 type: "adaptive" + output_config.effort 方式。
This page demonstrates special usage patterns for calling advanced features (such as Claude Reasoning) via the OpenAI SDK, including Extended Thinking, Adaptive Thinking, and streaming inference.
Basic Configuration
Before you begin, make sure you have obtained an API Key. If not, please refer to Create API Key.
Basic Information
- API Base URL:
https://api.agentsflare.com/v1 - Authentication: Bearer Token
- Content Type:
application/json
Claude Reasoning Compatibility Test
The following script uses the OpenAI SDK to test whether the relay station supports Claude Reasoning features, covering model list queries, basic requests, Extended Thinking, Adaptive Thinking, and streaming output tests.
#!/usr/bin/env python3
# ============================================================
# test_claude_reasoning.py
# Test if a third-party relay supports Claude Reasoning via OpenAI SDK
# Dependency: pip install openai
# ============================================================
import os
import json
import sys
from openai import OpenAI
import httpx
# ==================== Config Area ====================
BASE_URL = os.environ.get("BASE_URL", "https://api.agentsflare.com/v1")
API_KEY = os.environ.get("API_KEY", "sk-********")
MODEL = os.environ.get("MODEL", "claude-sonnet-4-6")
MAX_TOKENS = int(os.environ.get("MAX_TOKENS", "16384"))
BUDGET_TOKENS= int(os.environ.get("BUDGET_TOKENS", "8000"))
# =====================================================
# ANSI Colors
GREEN = "\033[92m"
RED = "\033[91m"
YELLOW = "\033[93m"
CYAN = "\033[96m"
RESET = "\033[0m"
def ok(msg): print(f"{GREEN}✅ {msg}{RESET}")
def fail(msg): print(f"{RED}❌ {msg}{RESET}")
def warn(msg): print(f"{YELLOW}⚠️ {msg}{RESET}")
def info(msg): print(f"{CYAN}{msg}{RESET}")
# Initialize OpenAI client (pointing to relay)
client = OpenAI(
api_key=API_KEY,
base_url=BASE_URL,
)
results: dict[str, bool] = {}
# ============================================================
# Utility: print response summary
# ============================================================
def print_response_summary(response):
"""Print key information from the response"""
print(f" Model : {response.model}")
print(f" Usage : prompt={response.usage.prompt_tokens}, "
f"completion={response.usage.completion_tokens}, "
f"total={response.usage.total_tokens}")
for i, choice in enumerate(response.choices):
msg = choice.message
# Detect thinking content (Claude puts thinking blocks in content)
if hasattr(msg, "content") and isinstance(msg.content, list):
for block in msg.content:
if hasattr(block, "type"):
if block.type == "thinking":
think_text = getattr(block, "thinking", "")
print(f" [Thinking] : {think_text[:120]}{'...' if len(think_text) > 120 else ''}")
elif block.type == "text":
print(f" [Answer] : {block.text[:200]}{'...' if len(block.text) > 200 else ''}")
else:
content = msg.content or ""
print(f" [Answer] : {content[:200]}{'...' if len(content) > 200 else ''}")
# ============================================================
# Test 0: List supported models
# ============================================================
def _parse_models(raw):
"""Defensively parse various /models response formats"""
# Standard OpenAI format: {"object":"list","data":[{"id":"..."}]}
if isinstance(raw, dict):
data = raw.get("data", [])
if isinstance(data, list):
for item in data:
if isinstance(item, dict):
if "id" in item:
yield item["id"]
elif "model" in item: # Some relays use model field
yield item["model"]
elif isinstance(item, str):
yield item
# Some relays return a JSON array directly
elif isinstance(raw, list):
for item in raw:
if isinstance(item, dict):
if "id" in item:
yield item["id"]
elif "model" in item:
yield item["model"]
elif isinstance(item, str):
yield item
def test_list_models():
info("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
info("[Test 0/4] Query supported Claude models")
info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
claude_models = []
# 1) Try standard OpenAI SDK approach first
try:
models = client.models.list()
if hasattr(models, "data") and isinstance(models.data, list):
claude_models = [m.id for m in models.data
if hasattr(m, "id") and "claude" in m.id.lower()]
else:
# Some SDK versions iterate models directly
claude_models = [m.id for m in models
if hasattr(m, "id") and "claude" in m.id.lower()]
except Exception as sdk_err:
warn(f"SDK parsing failed ({sdk_err}), trying direct HTTP request...")
# 2) Fallback: direct HTTP GET to /v1/models
try:
url = BASE_URL.rstrip("/") + "/models"
resp = httpx.get(url, headers={"Authorization": f"Bearer {API_KEY}"}, timeout=30)
resp.raise_for_status()
raw = resp.json()
all_models = list(_parse_models(raw))
claude_models = [m for m in all_models if "claude" in m.lower()]
except Exception as http_err:
fail(f"Query failed: SDK error={sdk_err}; HTTP fallback error={http_err}")
results["Model List Query"] = False
return
if claude_models:
ok(f"Found {len(claude_models)} Claude models:")
for name in sorted(claude_models):
print(f" • {name}")
else:
warn("No Claude models found. Please check if the relay supports Claude.")
results["Model List Query"] = True
# ============================================================
# Test 1: Basic request (no Thinking)
# ============================================================
def test_basic():
info("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
info("[Test 1/4] Basic request (no Thinking)")
info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
try:
response = client.chat.completions.create(
model=MODEL,
max_tokens=1024,
messages=[
{"role": "user", "content": "Hello, please introduce yourself in one sentence."}
],
)
ok(f"Basic request succeeded")
print_response_summary(response)
results["Basic Request"] = True
except Exception as e:
fail(f"Basic request failed: {e}")
results["Basic Request"] = False
# ============================================================
# Test 2: Extended Thinking (type: enabled + budget_tokens) — Legacy
# For Claude 3.7 Sonnet / Claude Sonnet 4.5 / Claude Opus 4.5
# Deprecated: Claude 4.6+ prefers "adaptive". See Test 3.
# ============================================================
def test_extended_thinking():
info("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
info("[Test 2/4] Extended Thinking (type: enabled + budget_tokens)")
info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
try:
response = client.chat.completions.create(
model=MODEL,
max_tokens=MAX_TOKENS,
messages=[
{
"role": "user",
"content": (
"Please reason step by step: A farmer has 17 sheep. All but 9 died. How many are left alive?"
),
}
],
# OpenAI SDK passes non-standard parameters via extra_body
extra_body={
"thinking": {
"type": "enabled",
"budget_tokens": BUDGET_TOKENS,
}
},
)
ok("Extended Thinking request succeeded")
print_response_summary(response)
results["Extended Thinking"] = True
except Exception as e:
fail(f"Extended Thinking failed: {e}")
results["Extended Thinking"] = False
# ============================================================
# Test 3: Adaptive Thinking (type: adaptive + output_config, Claude 4.6+)
# ============================================================
def test_adaptive_thinking():
info("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
info("[Test 3/4] Adaptive Thinking (type: adaptive + output_config, Claude 4.6+)")
info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
try:
response = client.chat.completions.create(
model=MODEL,
max_tokens=MAX_TOKENS,
messages=[
{
"role": "user",
"content": "Please think deeply: If 3^x + 3^x + 3^x = 3^12, what is the value of x?",
}
],
extra_body={
"thinking": {
"type": "adaptive",
},
"output_config": {
"effort": "high",
}
},
)
ok("Adaptive Thinking request succeeded")
print_response_summary(response)
results["Adaptive Thinking"] = True
except Exception as e:
warn(f"Adaptive Thinking failed (model may not support it): {e}")
results["Adaptive Thinking"] = False
# ============================================================
# Test 4: Streaming + Extended Thinking (Legacy: enabled mode)
# ============================================================
def test_streaming_thinking():
info("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
info("[Test 4/4] Streaming + Extended Thinking")
info("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
try:
stream = client.chat.completions.create(
model=MODEL,
max_tokens=MAX_TOKENS,
stream=True,
messages=[
{
"role": "user",
"content": "Please briefly explain what quantum entanglement is.",
}
],
extra_body={
"thinking": {
"type": "enabled",
"budget_tokens": BUDGET_TOKENS,
}
},
)
ok("Stream request established, receiving data...")
print(" [Stream Output]:", end=" ", flush=True)
char_count = 0
for chunk in stream:
delta = chunk.choices[0].delta if chunk.choices else None
if delta and delta.content:
print(delta.content, end="", flush=True)
char_count += len(delta.content)
if char_count > 300: # Preview first 300 chars only
print(" ...(truncated)", flush=True)
break
else:
print() # Newline
ok(f"Streaming + Thinking completed")
results["Streaming + Thinking"] = True
except Exception as e:
fail(f"Streaming + Thinking failed: {e}")
results["Streaming + Thinking"] = False
# ============================================================
# Summary Report
# ============================================================
def print_summary():
info("\n╔══════════════════════════════════════════╗")
info("║ 📊 Test Results Summary ║")
info("╚══════════════════════════════════════════╝")
passed = sum(1 for v in results.values() if v)
total = len(results)
for name, status in results.items():
mark = f"{GREEN}✅ Pass{RESET}" if status else f"{RED}❌ Fail{RESET}"
print(f" {name:<24} {mark}")
print()
if passed == total:
ok(f"All passed {passed}/{total} — Relay fully supports Claude Reasoning 🎉")
elif passed >= 2:
warn(f"Partially passed {passed}/{total} — Relay supports basic Claude features, but Reasoning support is incomplete")
else:
fail(f"Mostly failed {passed}/{total} — Please check BASE_URL / API_KEY / MODEL configuration")
print(f"""
{YELLOW}📌 Configuration:{RESET}
BASE_URL = {BASE_URL}
MODEL = {MODEL}
MAX_TOKENS = {MAX_TOKENS}
BUDGET_TOKENS = {BUDGET_TOKENS}
{YELLOW}📌 Notes:{RESET}
• Extended Thinking (type:enabled) → Claude 3.7 / 4.5 series (legacy, deprecated)
• Adaptive Thinking (type:adaptive) → Claude 4.6+ series (recommended)
• output_config.effort → low | medium | high | max (adaptive mode only)
• OpenAI SDK passes thinking parameters via extra_body
""")
# ============================================================
# Main Entry
# ============================================================
if __name__ == "__main__":
info("╔══════════════════════════════════════════╗")
info("║ Claude Reasoning Relay Compatibility Test ║")
info("╚══════════════════════════════════════════╝")
info(f"🔗 API URL : {BASE_URL}")
info(f"🤖 Model : {MODEL}")
info(f"🧠 Budget : {BUDGET_TOKENS} tokens")
test_list_models()
test_basic()
test_extended_thinking()
test_adaptive_thinking()
test_streaming_thinking()
print_summary()Key Parameters
| Parameter | Type | Description |
|---|---|---|
extra_body | dict | Field in OpenAI SDK for passing non-standard parameters |
thinking.type | string | enabled (Legacy, Claude 3.7 / 4.5 series) or adaptive (Claude 4.6+ series, recommended) |
thinking.budget_tokens | int | Maximum token budget allocated for the reasoning process (legacy enabled mode only) |
output_config.effort | string | Controls reasoning depth: low (minimal thinking), medium (default), high (deep thinking), max (maximum thinking, Opus 4.7+ only). Used with adaptive mode. |
Supported Models
The following Claude models support Reasoning via this method:
| Model | thinking.type Support | Note |
|---|---|---|
claude-sonnet-5 | adaptive only (recommended) | New |
claude-sonnet-4-6 | adaptive (recommended), enabled (deprecated) | New |
claude-opus-4-6 | adaptive (recommended), enabled (deprecated) | |
claude-sonnet-4-5 | enabled (legacy), adaptive not supported | |
claude-opus-4-5 | enabled (legacy), adaptive not supported | |
claude-3-7-sonnet | enabled (legacy), adaptive not supported |
- Claude 3.7 Sonnet: Supports
enabled(legacy). Migrate toadaptivewhen available. - Claude 4.5 series: Supports
enabled(legacy). Migrate toadaptivewhen available. - Claude 4.6 series (Opus/Sonnet): Supports
adaptive(recommended).enabledis deprecated. - Claude 4.7+ series: Only supports
adaptive. - Claude Sonnet 5: Supports
adaptiveonly — the newest Sonnet-tier model (1M context, new tokenizer).
Adaptive Thinking Example (Recommended)
# New way (recommended for Claude 4.6+)
response = client.chat.completions.create(
model="claude-sonnet-4-6",
max_tokens=16384,
messages=[{"role": "user", "content": "Explain quantum entanglement in simple terms."}],
extra_body={
"thinking": {"type": "adaptive"},
"output_config": {"effort": "high"}
},
)output_config.effort | Description |
|---|---|
low | Minimal thinking, fastest response |
medium | Default reasoning depth |
high | Deep reasoning |
max | Maximum reasoning depth (Opus 4.7+ only) |
Compatibility Notes
If you are using a third-party API relay service (such as New API, One API, etc.), please verify that the relay layer supports transparent forwarding of
thinking.type: "adaptive"parameters. Some older relay versions only support theenabledmode, which will causeadaptiverequests to return a 400 error.
Streaming Thinking Blocks
During streaming output, thinking content blocks may be interleaved with regular content blocks. When using tool use with streaming, thinking blocks must be retained and sent back to the API in subsequent requests as part of the assistant message. Removing them will result in API errors.
In tool use scenarios, thinking blocks must be preserved and passed back to the API verbatim throughout the entire assistant turn. If thinking blocks are removed, subsequent requests may be rejected by the API.
