स्कीमा सामान्यीकरण

ADK-Rust अनुरोध के समय प्रत्येक LLM प्रदाता के लिए MCP टूल स्कीमा को स्वचालित रूप से सामान्यीकृत करता है। इसका अर्थ है कि MCP टूल Gemini, OpenAI, Anthropic और अन्य प्रदाताओं में बिना मैन्युअल स्कीमा समायोजन के सहज रूप से काम करते हैं।

यह कैसे काम करता है

MCP Server → raw JSON Schema → McpToolset (stores verbatim)
                                      ↓
                          Model.generate_content()
                                      ↓
                          SchemaAdapter.normalize_schema()
                                      ↓
                          Provider API (Gemini/OpenAI/Anthropic)
  1. McpToolset टूल खोजता है और उनके मूल inputSchema को बिना किसी बदलाव के संग्रहीत करता है
  2. जब मॉडल अनुरोध बनाता है, तो वह प्रत्येक टूल के स्कीमा पर schema_adapter().normalize_schema() को कॉल करता है
  3. प्रत्येक प्रदाता का अपना अडैप्टर होता है, जो केवल उन्हीं रूपांतरणों को लागू करता है जिनकी उसके API को आवश्यकता होती है
  4. अनावश्यक सामान्यीकरण से बचने के लिए परिणामों को सामग्री हैश द्वारा कैश किया जाता है

प्रदाता का व्यवहार

सुविधाGeminiOpenAI सख्तOpenAIAnthropicGeneric
$ref रिज़ॉल्यूशन✅ इनलाइन करता है❌ संरक्षित रखता है❌ संरक्षित रखता है❌ संरक्षित रखता है❌ संरक्षित रखता है
anyOf/oneOfसमेटता हैसंरक्षित रखता हैसंरक्षित रखता हैसंरक्षित रखता हैसंरक्षित रखता है
allOfविलय करता हैसंरक्षित रखता हैसंरक्षित रखता हैसंरक्षित रखता हैसंरक्षित रखता है
additionalPropertiesहटाता हैfalse सेट करता हैसंरक्षित रखता हैसंरक्षित रखता हैसंरक्षित रखता है
प्रकार सारणियाँसंक्षिप्त करता हैसंरक्षित रखता हैसंरक्षित रखता हैसंरक्षित रखता हैसंरक्षित रखता है
$schemaहटाता हैहटाता हैहटाता हैहटाता हैहटाता है
if/then/elseहटा देता हैहटा देता हैहटा देता हैहटा देता हैहटा देता है
constenumenumenumसुरक्षित रखता हैenum
असमर्थित formatहटा देता हैहटा देता हैहटा देता हैसुरक्षित रखता हैहटा देता है
नेस्टिंग गहराई सीमा5 स्तरकोई नहींकोई नहींकोई नहींकोई नहीं
exclusiveMin/Maxहटाता हैसुरक्षित रखता हैसुरक्षित रखता हैसुरक्षित रखता हैसुरक्षित रखता है

SchemaAdapter ट्रेट

सभी एडेप्टर adk-core से इस ट्रेट को लागू करते हैं:

use serde_json::Value;
use std::borrow::Cow;

pub trait SchemaAdapter: Send + Sync + std::fmt::Debug {
    /// Normalize a raw JSON Schema for this provider.
    fn normalize_schema(&self, schema: Value) -> Value;

    /// Normalize a tool name (default: truncate to 64 bytes at UTF-8 boundary).
    fn normalize_tool_name<'a>(&self, name: &'a str) -> Cow<'a, str>;

    /// Fallback schema when no parameters_schema is provided.
    fn empty_schema(&self) -> Value;
}

प्रत्येक Llm इम्प्लीमेंटेशन schema_adapter() के माध्यम से अपना एडेप्टर लौटाता है:

use adk_core::Llm;

let model = GeminiModel::new(&api_key, "gemini-3.7-flash")?;
let adapter = model.schema_adapter(); // Returns &GeminiSchemaAdapter

उपलब्ध एडेप्टर

GeminiSchemaAdapter

सबसे आक्रामक एडेप्टर। Gemini के फ़ंक्शन-कॉलिंग API के लिए आवश्यक सभी विनाशकारी रूपांतरण लागू करता है:

use adk_gemini::schema_adapter::GeminiSchemaAdapter;
use adk_core::SchemaAdapter;

// Standard Gemini API
let adapter = GeminiSchemaAdapter::new();

// Vertex AI (sets additionalProperties: false instead of removing)
let adapter = GeminiSchemaAdapter::vertex_ai();

रूपांतरण पाइपलाइन:

  1. $ref को हल करें (डिफ़िनिशन से इनलाइन करें, गहराई 10 पर चक्रों को तोड़ें)
  2. $schema हटाएँ
  3. anyOf/oneOf को संक्षिप्त करें → पहला गैर-नल सब-स्कीमा
  4. allOf सब-स्कीमा मर्ज करें
  5. टाइप ऐरे संक्षिप्त करें (["string", "null"]"string")
  6. if/then/else हटाएँ
  7. const को एकल-तत्व enum में बदलें
  8. enum ऐरे से नल हटाएँ
  9. निहित type: "object" जोड़ें
  10. असमर्थित कीवर्ड हटाएँ
  11. असमर्थित format मान हटाएँ
  12. नेस्टिंग गहराई लागू करें (5 स्तर)
  13. definitions/$defs हटाएँ

OpenAiStrictSchemaAdapter

स्ट्रक्चर्ड आउटपुट के लिए additionalProperties: false जोड़ते हुए स्कीमा संरचना को सुरक्षित रखता है:

use adk_model::openai::OpenAiStrictSchemaAdapter;
use adk_core::SchemaAdapter;

let adapter = OpenAiStrictSchemaAdapter;

OpenAiSchemaAdapter

गैर-सख्त मोड के लिए न्यूनतम सुरक्षित सुधार:

use adk_model::openai::OpenAiSchemaAdapter;

let adapter = OpenAiSchemaAdapter;

AnthropicSchemaAdapter

लगभग पास-थ्रू — Anthropic अधिकांश JSON Schema सुविधाओं का समर्थन करता है:

use adk_model::anthropic::AnthropicSchemaAdapter;

let adapter = AnthropicSchemaAdapter;

GenericSchemaAdapter

अज्ञात प्रदाताओं (Ollama, DeepSeek आदि) के लिए डिफ़ॉल्ट:

use adk_core::GenericSchemaAdapter;

let adapter = GenericSchemaAdapter;

स्कीमा कैशिंग

अनावश्यक गणना से बचने के लिए सामान्यीकृत स्कीमा को कंटेंट हैश द्वारा कैश किया जाता है:

use adk_core::{GenericSchemaAdapter, SchemaCache};
use serde_json::json;
use std::sync::Arc;

let cache = SchemaCache::for_adapter(Arc::new(GenericSchemaAdapter));
let schema = json!({"type": "object", "properties": {"name": {"type": "string"}}});

// First call normalizes and caches
let result = cache.normalize(&schema);

// Subsequent calls return cached result (no re-normalization)
let cached = cache.normalize(&schema);

// Invalidate when tools change
cache.clear();

प्रत्येक कैश एक एडेप्टर इंस्टेंस का स्वामी होता है, इसलिए अलग-अलग प्रदाताओं या एडेप्टर कॉन्फ़िगरेशन के लिए सामान्यीकृत प्रविष्टियाँ आपस में टकरा नहीं सकतीं। प्रदाता क्लाइंट generate_content() के दौरान इन कैश का स्वचालित रूप से उपयोग करते हैं।

टूल नामों का संक्षिप्तीकरण

सभी एडेप्टर 64 बाइट से अधिक लंबाई वाले टूल नामों को मान्य UTF-8 वर्ण सीमाओं पर संक्षिप्त करते हैं:

use adk_core::SchemaAdapter;
use adk_gemini::schema_adapter::GeminiSchemaAdapter;

let adapter = GeminiSchemaAdapter::new();

// Short names pass through unchanged
let name = adapter.normalize_tool_name("get_weather");
assert_eq!(name, "get_weather");

// Long names are truncated to 64 bytes
let long = "mcp_server_github_com_organization_repository_pull_request_review_comments";
let truncated = adapter.normalize_tool_name(long);
assert!(truncated.len() <= 64);

// Multi-byte characters are never split
let emoji_name = "🔧_tool_名前が長い";
let result = adapter.normalize_tool_name(emoji_name);
assert!(std::str::from_utf8(result.as_bytes()).is_ok());

साझा यूटिलिटीज

adk_core::schema_utils मॉड्यूल कंपोज़ेबल ट्रांसफ़ॉर्म फ़ंक्शन प्रदान करता है, जिनका उपयोग एडेप्टर आंतरिक रूप से करते हैं:

use adk_core::schema_utils;
use serde_json::json;

let mut schema = json!({
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "status": { "const": "active" },
        "email": { "type": "string", "format": "hostname" }
    },
    "if": { "properties": { "x": { "type": "number" } } },
    "then": { "required": ["x"] }
});

// Apply individual transforms
schema_utils::strip_schema_keyword(&mut schema);
schema_utils::strip_conditional_keywords(&mut schema);
schema_utils::convert_const_to_enum(&mut schema);
schema_utils::strip_unsupported_formats(&mut schema, &["date-time", "email", "uri"]);

उपलब्ध यूटिलिटी:

  • strip_schema_keyword$schema हटाता है
  • strip_conditional_keywordsif/then/else हटाता है
  • add_implicit_object_typeproperties मौजूद होने पर type: "object" जोड़ता है
  • convert_const_to_enumconst को एकल-तत्व वाले enum में परिवर्तित करता है
  • strip_unsupported_formats — अनुमति-सूची में नहीं होने वाले फ़ॉर्मैट मान हटाता है
  • strip_null_from_enum — enum ऐरे से null हटाता है
  • truncate_tool_name — UTF-8 सीमा पर छोटा करता है
  • resolve_refs — डेफ़िनिशन से $ref संदर्भों को इनलाइन करता है
  • collapse_combinersanyOf/oneOf को पहले non-null मान में समेटता है
  • merge_all_ofallOf सब-स्कीमा को मर्ज करता है
  • collapse_type_arrays["string", "null"] को "string" में समेटता है
  • enforce_nesting_depth — गहरे स्कीमा को {"type": "object"} से प्रतिस्थापित करता है

कस्टम एडेप्टर

कस्टम प्रदाताओं के लिए SchemaAdapter लागू करें:

use adk_core::{SchemaAdapter, schema_utils};
use serde_json::Value;
use std::borrow::Cow;

#[derive(Debug)]
struct MyProviderAdapter;

impl SchemaAdapter for MyProviderAdapter {
    fn normalize_schema(&self, mut schema: Value) -> Value {
        // Apply only the transforms your provider needs
        schema_utils::strip_schema_keyword(&mut schema);
        schema_utils::strip_conditional_keywords(&mut schema);
        schema_utils::add_implicit_object_type(&mut schema);
        // Keep everything else as-is
        schema
    }
}

उदाहरण

सभी एडेप्टर को कार्य करते हुए देखने के लिए स्कीमा सामान्यीकरण डेमो चलाएँ:

cd examples/schema_normalization
cargo run

किसी API कुंजी की आवश्यकता नहीं है — यह स्थानीय रूप से सामान्यीकरण लॉजिक प्रदर्शित करता है।

sanitize_schema से माइग्रेशन

यदि आपने पहले सेनेटाइज़ किए गए स्कीमा लौटाने वाले McpToolset पर निर्भर किया था:

  • मानक उपयोग के लिए कोड में किसी बदलाव की आवश्यकता नहीं हैToolset trait API अपरिवर्तित है।
  • अब स्कीमा को टूल रजिस्ट्रेशन के समय नहीं, बल्कि मॉडल एडेप्टर द्वारा अनुरोध के समय सामान्यीकृत किया जाता है।
  • यदि आप parameters_schema() को कॉल कर रहे थे और Gemini-फ़ॉर्मैट किए गए आउटपुट की अपेक्षा कर रहे थे, तो अब इसके बजाय रॉ स्कीमा लौटाया जाता है। आवश्यकता होने पर इसे स्वयं सामान्यीकृत करने के लिए उपयुक्त SchemaAdapter का उपयोग करें।

पिछला: ← MCP टूल | अगला: सेशन →