# OpenAI function calling: modeliniz için bir read_url tool'u

> read_url tool'u ile OpenAI function calling: model için JSON şeması ve bağlantıları temiz Markdown'a dönüştüren Python döngüsü. KYC olmadan, kripto ile ödeme.

- URL: https://webreaderapi.com/tr/docs/openai/
- Son güncelleme: 2026-10-22
- Yayıncı: WebReaderAPI (https://webreaderapi.com)

Bir fonksiyon tanımlayın, `read_url`, ve model istediğinde çalıştırın. Model hangi sayfaların okunacağını seçer; kodunuz API'yi çağırır ve Markdown'u geri verir. Aynı şema, tool calling destekleyen diğer modellerle de çalışır.

**Hızlı yanıt — Bir OpenAI modelinin function calling ile web sayfalarını okumasını nasıl sağlarım?**

`tools` listesinde bir `read_url` fonksiyonu tanımlayın, ardından bir döngü çalıştırın: model bir tool call döndürdüğünde, **WebReaderAPI**'nin `/read` endpoint'ini URL ile çağırın ve Markdown'u bir `tool` mesajı olarak geri gönderin. Her sayfa 1 kredi, tarayıcıyla 2 kredi; Ekim 2026 itibarıyla $0,07/1K sayfa'den başlar. KYC yok; kripto ile ödeyin.

## read_url şeması nasıl görünüyor?

İki parametre yeterli: okunacak `url`, zorunlu, ve modelin uzun bir sayfayı kısa tutmasını sağlayan isteğe bağlı bir `max_chars`. En önemli kısım description: modele aracın ne döndürdüğünü ve ne zaman kullanılacağını söyler. Olgusal ve kısa tutun.

Aracı `web_fetch` yerine `read_url` olarak adlandırıyoruz; böylece bazı agent runtime'ların bu adla zaten sağladığı araçlarla çakışmıyoruz.

*Araç tanımı*

```json
{
  "type": "function",
  "function": {
    "name": "read_url",
    "description": "Read a public web page and return its main content as Markdown, with its title and source URL. Use it when the user gives a link or when a page must be read to answer.",
    "parameters": {
      "type": "object",
      "properties": {
        "url": { "type": "string", "description": "The http or https address of the page." },
        "max_chars": { "type": "integer", "description": "Most characters to return, 1000 to 500000. Default 20000." }
      },
      "required": ["url"],
      "additionalProperties": false
    }
  }
}
```

## Tool-calling döngüsü nasıl çalışır?

Konuşmayı `tools` listesiyle gönderin. Yanıt tool call'lar içeriyorsa, her birini çalıştırın, sonucu role `tool` ve eşleşen `tool_call_id` ile bir mesaj olarak ekleyin ve modeli tekrar sorun. Tool call içermeyen bir yanıt geldiğinde bu son yanıttır.

Tur sayısını sınırlayın. Birkaç sayfayla ilgili bir soru için üç veya dört yeterlidir ve bu sınır sizi sürekli daha fazlasını isteyen bir modelden korur.

*Python: openai paketiyle tam döngü*

```python
import json
import os

import requests
from openai import OpenAI

READ_URL = {
    "type": "function",
    "function": {
        "name": "read_url",
        "description": "Read a public web page and return its main content as Markdown, with its title and source URL.",
        "parameters": {
            "type": "object",
            "properties": {
                "url": {"type": "string", "description": "The http or https address of the page."},
                "max_chars": {"type": "integer", "description": "Most characters to return. Default 20000."},
            },
            "required": ["url"],
            "additionalProperties": False,
        },
    },
}


def read_url(url, max_chars=20000):
    resp = requests.get(
        "https://webreaderapi.com/api/v1/read",
        headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
        params={"url": url, "max_chars": max_chars},
        timeout=75,
    )
    body = resp.json()
    if resp.status_code != 200:
        return "Could not read the page: " + body["error"]["code"]
    return "# " + (body.get("title") or url) + "\nSource: " + body["final_url"] + "\n\n" + body["markdown"]


client = OpenAI()
model = os.environ.get("OPENAI_MODEL", "gpt-4.1-mini")
messages = [{"role": "user", "content": "What does https://example.com/blog/first-post announce? Answer in two sentences."}]

for _ in range(4):
    reply = client.chat.completions.create(model=model, messages=messages, tools=[READ_URL])
    msg = reply.choices[0].message
    if not msg.tool_calls:
        print(msg.content)
        break
    messages.append(msg)
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        messages.append({"role": "tool", "tool_call_id": call.id, "content": read_url(**args)})

```

## Token kullanımını ve maliyeti nasıl düşük tutarım?

Üç ayar önemli. `max_chars` değerini mütevazı tutun, sayfa başına yaklaşık 8.000 ila 20.000 karakter; çünkü döndürdüğünüz her karakter model tarafından okunur. Varsayılan `main_content=true` değerini koruyun, böylece menüler ve alt bilgiler bağlama hiçbir zaman ulaşmaz. Ve yukarıdaki gibi döngüyü sınırlayın, böylece tek bir soru düzinelerce okumayı tetikleyemez.

Bizim tarafta maliyet karakter başına değil, sayfa başına: 1 kredi = tarayıcı olmadan 1 sayfa okuma; sayfa JavaScript render etmek için tarayıcı gerektiriyorsa 2 kredi. Başarısız olan veya bir sitenin robots.txt'inin reddettiği istek için ücret alınmaz. Günde 300 sayfa okuyan bir destek asistanı ayda yaklaşık 9.000 kredi kullanır; bu 10.000 sayfa ($3,75) paketine sığar.

## Şema diğer modellerle de çalışıyor mu?

Evet, sarmalayıcıda küçük değişikliklerle. Çoğu tool-calling API'si parametreler için bir JSON Schema, araç için de bir ad ve description alır; dolayısıyla `read_url` sağlayıcılar arasında olduğu gibi taşınır. [MCP sayfası](https://webreaderapi.com/tr/docs/mcp/) aynı fonksiyonu Model Context Protocol konuşan istemciler için paketler ve [LangChain sayfası](https://webreaderapi.com/tr/docs/langchain/) onu LangChain ve LlamaIndex agent'ları için sarmalar.

## Bir sayfa reddedildiğinde model ne görmeli?

Yukarıdaki döngünün döndürdüğü gibi kısa, net bir cümle: "Could not read the page: blocked_by_robots". Modeller bunu iyi işler ve başka kaynaklara geçer veya kullanıcıya söyler. robots.txt'e uyarız: crawler'ımız kendini WebReaderAPI olarak tanıtır, kendisi için veya tüm robotlar için yazılmış kurallara uyar ve bir sitenin izin vermediği sayfayı okumaz. Reddedilen sayfalar için ücret alınmaz. Bir site isteğimizi reddederse, verdiği yanıtı döndürürüz: CAPTCHA'ları asla çözmeyiz, hesaplara giriş yapmayız veya bir engeli ya da ödeme duvarını aşmaya çalışmayız. Bu reddetmelerin hiçbiri kredi kullanmaz.

## Function calling: sık sorulan sorular

### Bunun için Responses API mi yoksa Chat Completions mı gerekiyor?

Örnek, `tools` parametresiyle Chat Completions kullanır. Aynı fonksiyon tanımı ve aynı `read_url` gövdesi, function tool kabul eden diğer OpenAI arayüzleriyle de çalışır; sadece etraflarındaki döngü değişir.

### Model tek bir turda birkaç sayfa okuyabilir mi?

Evet. Bir yanıt birkaç tool call içerebilir; döngü her birini çalıştırır ve modeli tekrar sormadan önce her sonucu döndürür. Model aynı anda çok sayfa okuduğunda `max_chars` değerini daha düşük tutun.

### API anahtarı modele açık mı?

Hayır. Anahtar kodunuzun ortamında kalır. Model yalnızca aracın adını, description'ını ve fonksiyonunuzun döndürdüğü metni görür.

### Reddedilen bir sayfanın maliyeti nedir?

Hiçbir şey. 1 kredi = tarayıcı olmadan 1 sayfa okuma; sayfa JavaScript render etmek için tarayıcı gerektiriyorsa 2 kredi. Başarısız olan veya bir sitenin robots.txt'inin reddettiği istek için ücret alınmaz.

---

WebReaderAPI: WebReaderAPI, AI ajanları için bir web reader API'sidir; herkese açık herhangi bir web sayfasını temiz Markdown'a dönüştürür ve kimlik yüklemeden kripto ile ödenir. $0,07/1K sayfa başlangıçlı ön ödemeli kreditler asla süresi dolmaz ve robots.txt'e uyulur. KYC yok — kimlik yok, selfie yok, belge yok. Kripto ile ödeme yapın.
