# Web arama API'siyle Python'da derin araştırma ajanı oluşturun

> Yaklaşık 60 satır Python ile derin araştırma ajanı oluşturun: sorguları planlayın, sayfayla arama yapın ve herhangi bir LLM ile atıflı yanıt yazın.

- URL: https://llmwebsearch.com/tr/guides/build-a-deep-research-agent/
- Son güncelleme: 2026-10-22
- Yayıncı: LLMWebSearch (https://llmwebsearch.com)

Derin araştırma bir model değil, bir döngüdür. Bu rehber, birkaç dakikada okuyabileceğiniz bir tane oluşturur: sorguları planlar, sayfa metni dahil olacak şekilde web'de arama yapar, her kaynağı bir kez tutar, boşlukları arar ve numaralı atıflarla bir yanıt yazar.

**Kısa yanıt — Python'da nasıl derin araştırma ajanı oluştururum?**

Bir LLM'e arama sorguları soran, her birini sayfa metni döndüren bir web arama API'si üzerinden çalıştıran, her kaynağı bir kez tutan, takip sorguları isteyen ve ardından atıflı bir yanıt yazan bir döngü yazın. **LLMWebSearch** ile her arama, ilk 3 sayfayı bir kredi karşılığında Markdown olarak döndürür; aşağıdaki betik soru başına altı arama çalıştırır. $1,20/1K arama itibarıyla KYC olmadan, kripto ile ödeme.

## Ajan ne yapacak?

1. **Plan** — Modelden, soruyu birlikte kapsayan dört kısa sorgu isteyin.
2. **Ara** — Her sorguyu read=3 ile çalıştırın; böylece ilk üç sayfa Markdown olarak geri dönsün.
3. **Kaynakları bir kez tutun** — Sonuçları URL'ye göre saklayın; zaten toplanmış veya metni olmayan sayfaları atlayın.
4. **Boşlukları bulun** — Şimdiye kadar bulunan başlıkları modele gösterin ve eksik olanlar hakkında iki sorgu isteyin.
5. **Yazın** — En fazla 12 kaynağı numaralandırın ve bunları [1], [2] biçiminde atıflayan bir yanıt isteyin.

## Başlamadan önce neye ihtiyacım var?

Üç şey:

- **Bir LLMWebSearch API anahtarı**, `LLMWEBSEARCH_API_KEY` ortam değişkeninde. Anahtarlar, ilk paketinizden sonra panoda görünür.
- **Herhangi bir OpenAI uyumlu sohbet endpoint'i**, `LLM_BASE_URL`, `LLM_API_KEY` ve `LLM_MODEL` ile ayarlanır. Barındırılan modeller ve yerel sunucular da çalışır.
- **Python 3.9 veya üstü** ve `requests` paketi.

Betik her iki servis için de düz HTTP kullanır; yani arama kodunu değiştirmeden modeli değiştirebilirsiniz.

*Python: deep_research.py*

```python
import os

import requests

SEARCH = "https://llmwebsearch.com/api/v1/search"
SEARCH_HEADERS = {"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]}
# Any OpenAI-compatible chat endpoint works here: set your own base URL, key and model name.
LLM_URL = os.environ.get("LLM_BASE_URL", "https://llm.example.com/v1") + "/chat/completions"
LLM_HEADERS = {"Authorization": "Bearer " + os.environ.get("LLM_API_KEY", "")}
MODEL = os.environ.get("LLM_MODEL", "your-model-name")


def ask_llm(prompt):
    body = {"model": MODEL, "messages": [{"role": "user", "content": prompt}]}
    resp = requests.post(LLM_URL, headers=LLM_HEADERS, json=body, timeout=120)
    resp.raise_for_status()
    return resp.json()["choices"][0]["message"]["content"]


def plan_queries(question, n=4):
    text = ask_llm(f"Write {n} short web search queries, one per line, to answer: {question}")
    queries = [line.strip("-*0123456789. ").strip() for line in text.splitlines()]
    return [q for q in queries if q][:n]


def search(query):
    body = {"q": query, "max_results": 5, "read": 3, "max_chars": 5000}
    resp = requests.post(SEARCH, headers=SEARCH_HEADERS, json=body, timeout=60)
    resp.raise_for_status()
    return resp.json()["results"]


def research(question, rounds=2):
    sources = {}  # url -> result, so the same page is never cited twice
    queries = plan_queries(question)
    for _ in range(rounds):
        for query in queries:
            for r in search(query):
                if r.get("content_status") == "ok" and r["url"] not in sources:
                    sources[r["url"]] = r
        notes = "\n".join(f"- {r['title']}" for r in sources.values())
        queries = plan_queries(f"{question}\nAlready found:\n{notes}\nWhat is still missing?", n=2)
    numbered = list(sources.values())[:12]
    context = "\n\n".join(
        f"[{i}] {r['title']} ({r['url']})\n{r['content']}" for i, r in enumerate(numbered, 1)
    )
    prompt = (
        "Answer the question using only the sources below. Cite them as [1], [2]. "
        "Say so when the sources disagree or do not cover a point.\n\n"
        f"Question: {question}\n\nSources:\n{context}"
    )
    return ask_llm(prompt), [r["url"] for r in numbered]


if __name__ == "__main__":
    answer, urls = research("What changed in the EU rules for general-purpose AI models in 2025?")
    print(answer)
    for i, url in enumerate(urls, 1):
        print(f"[{i}] {url}")
```

## Her bir parça nasıl çalışır?

`plan_queries` modelden her satırda bir tane olacak şekilde kısa sorgular ister ve liste işaretlerini kaldırır. Kısa sorgular, arama motorlarının sayfaları sıralama biçimine tam sorulardan daha iyi uyar.

`search`, `POST https://llmwebsearch.com/api/v1/search`'ü `max_results=5`, `read=3` ve `max_chars=5000` ile çağırır. Yanıt beş sonuç listeler; ilk üçü sayfa metnini `content` içinde taşır.

`research` turları yürütür. Kaynakları URL ile anahtarlanmış bir sözlükte tutar; böylece iki sorguyla bulunan bir sayfa bir kez sayılır. Yalnızca `content_status` değeri `ok` olan sonuçlar tutulur, çünkü yanıt modelin okuyabildiği metne dayanmalıdır.

Her turdan sonra model, şimdiye kadar toplanan başlıkları görür ve eksik olanlar için iki yeni sorgu önerir. Son prompt en fazla on iki kaynağı numaralandırır ve atıf kurallarını belirler.

## Bir raporun maliyeti ne kadar?

Varsayılan ayarlarla soru başına altı arama: ilk turda dört, ikinci turda iki. `read` değeri 3 iken bu altı kredidir. Dolayısıyla $41,25 değerindeki 25.000 arama, 4.000'den fazla raporu kapsar.

Model çağrıları LLM faturanıza ek maliyet getirir: rapor başına üç planlama çağrısı ve bir uzun yanıt çağrısı. Yanıt çağrısı 5.000 karakterlik en fazla on iki sayfa taşır; modeliniz pahalıysa `max_chars` değerini düşürün.

## Daha derine inmesini nasıl sağlarım?

Yapıyı değil, sayıları değiştirin:

- **Daha fazla tur.** `rounds=4`, modelin iki tur daha boşlukları kovalamasını sağlar.
- **Tur başına daha fazla sorgu.** Boşluk bulma çağrısındaki `n` değerini 2'den 4'e çıkarın.
- **Daha dar kaynaklar.** Resmi veya akademik siteler için arama gövdesine `include_domains` ekleyin.
- **Yalnızca güncel materyal.** `"time_range": "month"` veya `"topic": "news"` ekleyin.
- **Sorgu başına daha fazla sayfa.** `read=5` beş sayfa okur, arama başına 2 kredi.

## Ajanı güvende ve kibar nasıl tutarım?

Her sayfayı güvenilmeyen metin olarak ele alın. Son prompt, modele kaynakları yalnızca kanıt olarak kullanmasını söyler; kaynakların içindeki talimatların yok sayılması gerektiğine dair açık bir satır ekleyin. Bir kaynağın asla bir araç çağrısını veya dosya yazmayı tetiklemesine izin vermeyin.

Web tarafında, Okuyucumuz robots.txt'ye uyar: kendini LLMWebSearch olarak tanıtır, bir sitenin onun için ya da tüm robotlar için yazdığı kurallara uyar ve okumasına izin verilmeyen her sayfanın içeriğini dışarıda bırakır. Erişimi reddeden sayfalar içerik olmadan döner ve script bunları atlar. Bir site okuyucumuzu geri çevirdiğinde sonuç, içerik olmadan ve sitenin durumuyla döner: CAPTCHA'ları asla çözmeyiz, hesaplara giriş yapmayız veya bir engeli ya da ödeme duvarını aşmaya çalışmayız.

## Neler ters gidebilir?

Testte üç şey ortaya çıkıyor:

- **Belirsiz sorgular.** Plan zayıfsa her tur aynı sayfaları bulur. Modelden belirli adlar ve tarihler içeren sorgular isteyin.
- **Metinli çok az kaynak.** Bazı konular ödeme duvarlarının arkasında. Sorguları genişletin veya daha fazla sonuca izin verin.
- **Aşırı uzun prompt'lar.** On iki uzun sayfa küçük bir modelin bağlamını aşabilir. `max_chars` değerini düşürün veya sekiz kaynak tutun.

Her sorguyu ve döndürdüğü URL'leri loglayın. Bu logu okumak, plan prompt'unu geliştirmenin en hızlı yoludur.

## Derin araştırma ajanı: sık sorulan sorular

### Bunu yerel bir modelle çalıştırabilir miyim?

Evet, yerel sunucu OpenAI chat-completions formatını konuşuyorsa. `LLM_BASE_URL` değerini adresine, `LLM_MODEL` değerini model adına ayarlayın.

### Bunu bir MCP aracına dönüştürebilir miyim?

Evet. `research()` fonksiyonunu bir MCP aracına sarın veya ajanınıza [MCP sayfasındaki](https://llmwebsearch.com/tr/docs/mcp/) düz arama aracını verin ve döngüyü kendisinin çalıştırmasına izin verin.

### Neden arama API'sinden doğrudan bir cevap istemiyorum?

Çünkü LLMWebSearch cevap yazmaz. API yazılı bir yanıt değil kaynaklar döndürür: sayfaları kendi modeliniz okur, yanıtı yazar ve URL'leri alıntılar.

### Her aramanın maliyetini nasıl görürüm?

Her yanıt `credits_used` içerir ve `GET https://llmwebsearch.com/api/v1/credits` kalan bakiyenizi ücretsiz gösterir.

---

LLMWebSearch: LLMWebSearch, AI ajanları için bir web arama API'sidir; sıralanmış sonuçları en iyi sayfaların Markdown içeriğiyle birlikte döndürür ve kripto ile ödenir, kimlik yüklemesi gerekmez. $1,20/1K arama kredilik ön ödemeli krediler hiç süresi dolmaz. KYC yok — kimlik yok, selfie yok, belge yok. Kripto ile ödeme.
