पाठ 12 / 31

Errors, Validation और उबरने-योग्य विफलताएँ

Protocol errors और tool errors में अंतर करें और मॉडल को उबरने में मदद करें।

दो तरह की विफलता

दो जगह गड़बड़ होती है। Protocol errors JSON-RPC errors हैं, जैसे अज्ञात method (-32601) या ग़लत बना request, जिन्हें SDK सँभालता है। Tool execution errors वैध call के भीतर होती हैं (ग़लत arguments, नीचे की सेवा का विफल होना); उन्हें tool परिणाम में isError: true और साफ़ संदेश के साथ रिपोर्ट करना चाहिए ताकि पूरा run विफल होने की जगह मॉडल उसे पढ़कर सुधार सके ("order_id ठीक 6 अंकों का होना चाहिए")। इनपुट schema से और कोड में validate करें; मॉडल के दिए arguments पर भरोसा कभी न करें, ख़ासकर file paths, SQL, shell commands और URLs के लिए। Error पाठ में stack traces, secrets या आंतरिक hostnames लीक न करें।

असली server पर दोनों विफलता प्रकार, चलाकर

मैंने यह पहले दिखाए असली server के विरुद्ध चलाया, virtual environment में आधिकारिक mcp Python SDK 2.2.0 के साथ; client पक्ष stdio पर कच्चा JSON-RPC है, SDK के बिना। Server को उसी folder में server.py नाम से सहेजें। SDK के नाम और डिफ़ॉल्ट संस्करणों के बीच बदलते हैं, इसलिए मौजूदा दस्तावेज़ देखें। अमान्य id ऐसा सामान्य result लौटाता है जिसका पाठ साफ़ error संदेश है जिस पर मॉडल कार्य कर सके। ग़ायब argument schema validation में विफल होता है और isError true के साथ आता है। अज्ञात method protocol error कोड -32601 के साथ देता है।

import json, subprocess, sys

proc = subprocess.Popen([sys.executable, "server.py"], stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True)

def send(msg):
    proc.stdin.write(json.dumps(msg) + "\n"); proc.stdin.flush()

def call(id_, method, params=None):
    send({"jsonrpc": "2.0", "id": id_, "method": method, **({"params": params} if params is not None else {})})
    return json.loads(proc.stdout.readline())

init = call(1, "initialize", {"protocolVersion": "2025-06-18", "capabilities": {},
                              "clientInfo": {"name": "demo-client", "version": "0.1"}})
print("server:", init["result"]["serverInfo"]["name"], "| protocol:", init["result"]["protocolVersion"])
print("capabilities:", sorted(init["result"]["capabilities"]))
send({"jsonrpc": "2.0", "method": "notifications/initialized"})     # a notification: no id, no reply

tools = call(2, "tools/list")["result"]["tools"]
print("tools:", [t["name"] for t in tools])
print("input schema:", json.dumps(tools[0]["inputSchema"]))

ok = call(3, "tools/call", {"name": "get_order_status", "arguments": {"order_id": "481516"}})
print("call ok     :", ok["result"]["content"][0]["text"], "| isError:", ok["result"].get("isError"))
bad = call(4, "tools/call", {"name": "get_order_status", "arguments": {"order_id": "12"}})
print("call bad id :", bad["result"]["content"][0]["text"])
missing = call(5, "tools/call", {"name": "get_order_status", "arguments": {}})
print("missing arg :", "isError" , missing["result"].get("isError"), "|", missing["result"]["content"][0]["text"][:60].replace(chr(10), " "))
unknown = call(6, "no/such/method")
print("unknown     :", unknown["error"]["code"], unknown["error"]["message"])

res = call(7, "resources/list")["result"]["resources"]
print("resources:", [r["uri"] for r in res])
print("read:", call(8, "resources/read", {"uri": "policy://refunds"})["result"]["contents"][0]["text"])
pr = call(9, "prompts/get", {"name": "triage", "arguments": {"ticket": "I was charged twice"}})
print("prompt:", pr["result"]["messages"][0]["content"]["text"])
proc.stdin.close(); proc.wait()

Output:

server: demo-orders | protocol: 2025-06-18
capabilities: ['experimental', 'prompts', 'resources', 'tools']
tools: ['get_order_status']
input schema: {"properties": {"order_id": {"title": "Order Id", "type": "string"}}, "required": ["order_id"], "type": "object", "title": "get_order_statusArguments"}
call ok     : {
  "order_id": "481516",
  "status": "shipped"
} | isError: False
call bad id : {
  "error": "order_id must be exactly 6 digits"
}
missing arg : isError True | Error executing tool get_order_status: 1 validation error fo
unknown     : -32601 Method not found
resources: ['policy://refunds']
read: Refunds above 5000 rupees need approval.
prompt: Classify this ticket as billing, technical or other: I was charged twice

त्वरित जाँच: मॉडल की मदद के लिए tool को ग़लत arguments कैसे रिपोर्ट करने चाहिए?

  • Server क्रैश करके
  • Tool परिणाम में साफ़, विशिष्ट संदेश के साथ
  • पूरे stack trace के साथ
  • कुछ न लौटाकर
Answer

Tool परिणाम में साफ़, विशिष्ट संदेश के साथ — कार्रवाई-योग्य संदेश मॉडल को अगले चरण में ख़ुद सुधरने देते हैं।