# Anthropic SDK से पूरा Tool Loop — Claude API / OpenAI API की बुनियाद

Source: https://www.geekswithgeeks.com/hi/llm-apis/t-anthropic

> Tool परिभाषित करें, tool_use पहचानें, tool_result लौटाएँ।

## tool_use blocks और tool_result blocks

Anthropic में tools `name`, `description` और `input_schema` के साथ सूचीबद्ध होते हैं। `stop_reason == "tool_use"` वाले उत्तर में एक या अधिक **`tool_use` content blocks** होते हैं (प्रत्येक में `id`, tool `name` और उसका `input` dict)। आप पूरा assistant उत्तर `messages` में जोड़ते हैं, फिर ऐसा **user message** जोड़ते हैं जिसकी सामग्री **`tool_result` blocks** की सूची है, हर एक संबंधित `tool_use_id` का संदर्भ देता है। Errors को raise करने की जगह परिणाम में पाठ (वैकल्पिक रूप से error चिह्नित) के रूप में लौटाएँ, ताकि मॉडल उबर सके। हमेशा **loop चरणों की सीमा** रखें।

## Anthropic tool loop, चलाकर

मैंने यह Python virtual environment में anthropic 1.11.0 और openai 3.22.1 SDKs के साथ छोटे स्थानीय stand-in server (testing विषय में दिखाया, `mock.py` नाम से सहेजा) के विरुद्ध चलाया। Server तैयार उत्तर लौटाता है, इसलिए कोई key, network या असली मॉडल शामिल नहीं: यह साबित करता है कि SDK requests कैसे बनाता और उत्तर कैसे सँभालता है, यह नहीं कि असली मॉडल क्या कहता। Stand-in server पहली call पर `get_order_status` माँगता है और दूसरी पर पाठ लौटाता है। Loop माँगा गया tool और arguments छापता है, स्थानीय function चलाता है, और 2 API calls के बाद अंतिम उत्तर पर समाप्त होता है।

```python
import json
import mock, anthropic, openai
srv = mock.start(); base = f"http://127.0.0.1:{srv.server_address[1]}"      # local stand-in server, not a real API

client = anthropic.Anthropic(api_key="k", base_url=base)
tools = [{"name": "get_order_status", "description": "Look up an order by 6-digit id.",
          "input_schema": {"type": "object", "properties": {"order_id": {"type": "string"}}, "required": ["order_id"]}}]
def get_order_status(order_id): return {"order_id": order_id, "status": "shipped"}

messages = [{"role": "user", "content": "Where is order 481516?"}]
for step in range(5):                                           # always cap the loop
    reply = client.messages.create(model="demo-model", max_tokens=200, tools=tools, messages=messages)
    if reply.stop_reason != "tool_use":
        print("final:", reply.content[0].text); break
    messages.append({"role": "assistant", "content": reply.content})
    results = []
    for block in reply.content:
        if block.type == "tool_use":
            print("model asked for:", block.name, block.input)
            results.append({"type": "tool_result", "tool_use_id": block.id,
                            "content": json.dumps(get_order_status(**block.input))})
    messages.append({"role": "user", "content": results})
print("calls to the API:", len(mock.STATE["log"]))

```

Output:

```
model asked for: get_order_status {'order_id': '481516'}
final: Your order 481516 has shipped.
calls to the API: 2
```

## Errors को परिणाम के रूप में लौटाएँ

Tool विफल हो तो error पाठ को tool परिणाम के रूप में भेजें ताकि loop क्रैश होने की जगह मॉडल समझा या retry कर सके।

**Quiz:** tool_result block अनुरोध से कैसे जुड़ता है?

- [ ] API key से
- [x] tool_use block id से मेल खाते tool_use_id से
- [ ] मॉडल नाम से
- [ ] वह नहीं जुड़ता

*Answer:* tool_use block id से मेल खाते tool_use_id से. हर परिणाम को उस call की id का संदर्भ देना होता है जिसका वह उत्तर है।
