---
title: "Yapay ZekÃ¢ Entegrasyonu (Claude API)"
url: "https://cilginyazilim.com/kutuphane/php-ai-integration"
description: "Bu Ã¶rnek, Anthropic Claude Messages API'sini PHP 8 tabanlÄ±, oturum giriÅŸli bir panele baÄŸlar ve bunu hiÃ§bir SDK kullanmadan yapar: istek cURL ile atÄ±lÄ±r, yanÄ±t elle ayrÄ±ÅŸtÄ±rÄ±lÄ±r. Ã–ne Ã§Ä±kan dÃ¶rt karar vardÄ±r. Birincisi gÃ¼venlik: API anahtarÄ± .env dosyasÄ±nda durur ve yalnÄ±zca sunucuda kullanÄ±lÄ±r, tarayÄ±cÄ±ya hiÃ§ gÃ¶nderilmez â€” anahtarÄ± JavaScript'e koymak onu sayfayÄ± aÃ§an herkese vermek demektir. Ä°kincisi maliyet gÃ¶rÃ¼nÃ¼rlÃ¼ÄŸÃ¼: her mesajÄ±n giriÅŸ ve Ã§Ä±kÄ±ÅŸ jetonu API'nin usage alanÄ±ndan okunur, maliyet fiyat tablosundan hesaplanÄ±r ve hem mesaj hem sohbet dÃ¼zeyinde saklanÄ±r; sohbet toplamÄ± mesaj toplamlarÄ±na birebir eÅŸittir. ÃœÃ§Ã¼ncÃ¼sÃ¼ dayanÄ±klÄ±lÄ±k: 429, 529 ve 5xx yanÄ±tlarÄ± geÃ§ici sayÄ±lÄ±p Ã¼stel geri Ã§ekilme ve jitter ile en fazla Ã¼Ã§ kez yeniden denenir, 401 ve 400 ise kalÄ±cÄ± sayÄ±lÄ±p hiÃ§ denenmez. DÃ¶rdÃ¼ncÃ¼sÃ¼ doÄŸruluk: stop_reason ve refusal alanlarÄ± ayrÄ± ele alÄ±nÄ±r, bÃ¶ylece kesilmiÅŸ bir yanÄ±t tam gibi ya da modelin bilinÃ§li reddi sunucu hatasÄ± gibi gÃ¶sterilmez. Modelin dÃ¼ÅŸÃ¼nme Ã¶zeti de saklanÄ±r ve arayÃ¼zde katlanarak sunulur."
published: "2026-09-03T09:44:20+03:00"
modified: "2026-09-05T01:50:57+03:00"
category: "Uygulama Ä°skeleti"
type: "kod Ã¶rneÄŸi"
difficulty: "Ä°leri"
tech: ["PHP 8", "PDO", "MySQL", "Bootstrap 5", "Ajax", "Oturum GiriÅŸi"]
tags: ["Claude API", "cURL", "Jeton Takibi", "LLM", "Maliyet", "Yapay ZekÃ¢"]
license: "MIT"
site: "CÄ±lgÄ±nYazÄ±lÄ±m"
language: "tr"
---

# Yapay ZekÃ¢ Entegrasyonu (Claude API)

Bu Ã¶rnek, Anthropic Claude Messages API'sini PHP 8 tabanlÄ±, oturum giriÅŸli bir panele baÄŸlar ve bunu hiÃ§bir SDK kullanmadan yapar: istek cURL ile atÄ±lÄ±r, yanÄ±t elle ayrÄ±ÅŸtÄ±rÄ±lÄ±r. Ã–ne Ã§Ä±kan dÃ¶rt karar vardÄ±r. Birincisi gÃ¼venlik: API anahtarÄ± .env dosyasÄ±nda durur ve yalnÄ±zca sunucuda kullanÄ±lÄ±r, tarayÄ±cÄ±ya hiÃ§ gÃ¶nderilmez â€” anahtarÄ± JavaScript'e koymak onu sayfayÄ± aÃ§an herkese vermek demektir. Ä°kincisi maliyet gÃ¶rÃ¼nÃ¼rlÃ¼ÄŸÃ¼: her mesajÄ±n giriÅŸ ve Ã§Ä±kÄ±ÅŸ jetonu API'nin usage alanÄ±ndan okunur, maliyet fiyat tablosundan hesaplanÄ±r ve hem mesaj hem sohbet dÃ¼zeyinde saklanÄ±r; sohbet toplamÄ± mesaj toplamlarÄ±na birebir eÅŸittir. ÃœÃ§Ã¼ncÃ¼sÃ¼ dayanÄ±klÄ±lÄ±k: 429, 529 ve 5xx yanÄ±tlarÄ± geÃ§ici sayÄ±lÄ±p Ã¼stel geri Ã§ekilme ve jitter ile en fazla Ã¼Ã§ kez yeniden denenir, 401 ve 400 ise kalÄ±cÄ± sayÄ±lÄ±p hiÃ§ denenmez. DÃ¶rdÃ¼ncÃ¼sÃ¼ doÄŸruluk: stop_reason ve refusal alanlarÄ± ayrÄ± ele alÄ±nÄ±r, bÃ¶ylece kesilmiÅŸ bir yanÄ±t tam gibi ya da modelin bilinÃ§li reddi sunucu hatasÄ± gibi gÃ¶sterilmez. Modelin dÃ¼ÅŸÃ¼nme Ã¶zeti de saklanÄ±r ve arayÃ¼zde katlanarak sunulur.

- **Gereksinim:** PHP 8.0+ Â· MySQL 5.7+ / MariaDB 10.3+ Â· pdo_mysql Â· mbstring Â· curl Â· Anthropic API anahtarÄ± Â· Apache mod_rewrite
- **Kod deposu:** https://github.com/CilginYazilim/ai-integration-system

## Ã–ne Ã‡Ä±kan Ã–zellikler

- API anahtarÄ± yalnÄ±zca sunucuda; tarayÄ±cÄ±ya hiÃ§ gÃ¶nderilmez
- Mesaj baÅŸÄ±na giriÅŸ/Ã§Ä±kÄ±ÅŸ jetonu ve hesaplanmÄ±ÅŸ maliyet kaydÄ±
- Sohbet toplamlarÄ± mesaj toplamlarÄ±yla birebir tutarlÄ±
- GiriÅŸ jetonunun neden her mesajda arttÄ±ÄŸÄ± somut olarak gÃ¶rÃ¼nÃ¼r
- GeÃ§ici (429/529/5xx) ve kalÄ±cÄ± (401/400) hata ayrÄ±mÄ±
- Ãœstel geri Ã§ekilme + jitter ile en fazla Ã¼Ã§ yeniden deneme
- stop_reason ve refusal alanlarÄ± ayrÄ± ele alÄ±nÄ±r
- Modelin dÃ¼ÅŸÃ¼nme Ã¶zeti saklanÄ±r ve details ile katlanarak gÃ¶sterilir
- SDK yok: istek cURL ile atÄ±lÄ±r, yanÄ±t elle ayrÄ±ÅŸtÄ±rÄ±lÄ±r

## KullanÄ±m SenaryolarÄ±

- Projesine yapay zekÃ¢ Ã¶zelliÄŸi ekleyip maliyeti kontrol altÄ±nda tutmak isteyenler
- API anahtarÄ±nÄ± nereye koyacaÄŸÄ±nÄ± soran geliÅŸtiriciler
- Jeton muhasebesini ve maliyet hesabÄ±nÄ± Ã¶ÄŸrenmek isteyenler
- SDK kurmadan, saf PHP ile Messages API'sine baÄŸlanmak isteyenler

## Kurulum

1. Depoyu klonlayÄ±n veya ZIP olarak indirip web kÃ¶kÃ¼nÃ¼ze aÃ§Ä±n
2. database.sql dosyasÄ±nÄ± iÃ§e aktarÄ±n (veritabanÄ±nÄ± kendisi oluÅŸturur)
3. .env.example dosyasÄ±nÄ± .env adÄ±yla kopyalayÄ±n
4. .env iÃ§ine ANTHROPIC_API_KEY deÄŸerinizi yazÄ±n (console.anthropic.com)
5. TarayÄ±cÄ±dan aÃ§Ä±p admin@cilginyazilim.com / Admin1234 ile giriÅŸ yapÄ±n

## AyrÄ±ntÄ±lÄ± AnlatÄ±m

<img src="assets/images/logo.png" alt="Ã‡Ä±lgÄ±n YazÄ±lÄ±m" width="90">

## Yapay ZekÃ¢ Entegrasyonu (Gemini Â· Groq Â· Claude)

#### PHP 8 Â· PDO Â· MySQL Â· Ãœcretsiz API AnahtarÄ±yla Ã‡alÄ±ÅŸÄ±r Â· Jeton ve Maliyet Takibi Â· DeÄŸiÅŸtirilebilir SaÄŸlayÄ±cÄ± Â· Ã‡Ä±lgÄ±n YazÄ±lÄ±m TasarÄ±m KalÄ±bÄ±

**Ãœcretsiz bir anahtarla Ã§alÄ±ÅŸÄ±r. Anahtar sunucuda kalÄ±r, her yanÄ±tÄ±n maliyeti hesaplanÄ±r, sohbet geÃ§miÅŸi veritabanÄ±nda durur.**

[![PHP](https://img.shields.io/badge/PHP-8.0%2B-777BB4?style=flat-square&logo=php&logoColor=white)](https://php.net)
[![MySQL](https://img.shields.io/badge/MySQL-5.7%2B-4479A1?style=flat-square&logo=mysql&logoColor=white)](https://mysql.com)
[![Gemini](https://img.shields.io/badge/Gemini-%C3%BCcretsiz_katman-1a73e8?style=flat-square&logo=googlegemini&logoColor=white)](https://aistudio.google.com/apikey)
[![SaÄŸlayÄ±cÄ±](https://img.shields.io/badge/Sa%C4%9Flay%C4%B1c%C4%B1-de%C4%9Fi%C5%9Ftirilebilir-16a34a?style=flat-square)](#saÄŸlayÄ±cÄ±-seÃ§mek)
[![Composer](https://img.shields.io/badge/Composer-gerekmiyor-16a34a?style=flat-square)](#kurulum)
[![License](https://img.shields.io/badge/Lisans-MIT-16a34a?style=flat-square)](LICENSE)

**ðŸ‡¹ðŸ‡· TÃ¼rkÃ§e** Â· [ðŸ‡¬ðŸ‡§ English](README.en.md)

[**â–¶ CanlÄ± Demo**](https://cilginyazilim.com/kutuphane/uygulama/ai-integration-system/) Â· [Kaynak KÃ¼tÃ¼phanesi](https://cilginyazilim.com/kutuphane/php-ai-integration) Â· [cilginyazilim.com](https://cilginyazilim.com)

---

### CanlÄ± Demo

**Kurulum yok, kayÄ±t yok, indirme yok â€” tarayÄ±cÄ±nÄ±zdan 3 saniyede deneyin.**

<a href="https://cilginyazilim.com/kutuphane/uygulama/ai-integration-system/"><img src="https://img.shields.io/badge/CANLI_DEMOYU_A%C3%87-0b5cb5?style=for-the-badge&logo=googlechrome&logoColor=white&labelColor=061321" alt="CanlÄ± Demoyu AÃ§" height="42"></a>
<a href="https://cilginyazilim.com/kutuphane/php-ai-integration"><img src="https://img.shields.io/badge/KAYNAK_KODU_%C4%B0NCELE-0ea5e9?style=for-the-badge&logo=readthedocs&logoColor=white&labelColor=061321" alt="Kaynak Kodu Ä°ncele" height="42"></a>
<a href="https://github.com/CilginYazilim/ai-integration-system/archive/refs/heads/main.zip"><img src="https://img.shields.io/badge/ZIP_%C4%B0ND%C4%B0R-16a34a?style=for-the-badge&logo=github&logoColor=white&labelColor=061321" alt="ZIP Ä°ndir" height="42"></a>

<br><br>

<a href="https://cilginyazilim.com/kutuphane/uygulama/ai-integration-system/" title="CanlÄ± demoyu aÃ§mak iÃ§in tÄ±klayÄ±n">
  <img src="docs/screenshots/04-sohbet-detay.png" alt="Yapay zekÃ¢ entegrasyonu canlÄ± demo Ã¶nizlemesi" width="860">
</a>

<sub>â–² GÃ¶rsele tÄ±klayarak demoyu aÃ§abilirsiniz</sub>

<br>

#### Demo hesaplarÄ±

| Rol | E-posta | Parola |
|---|---|---|
| YÃ¶netici | `admin@cilginyazilim.com` | `Admin1234` |
| KullanÄ±cÄ± | `demo@cilginyazilim.com` | `Demo1234` |

#### Demoda 60 saniyede neleri deneyebilirsiniz?

| # | Åžunu deneyin | Perde arkasÄ±nda ne oluyor? |
|---|---|---|
| **1** | **Sohbetler** sayfasÄ±nÄ± aÃ§Ä±n ve dÃ¶rt sayaca bakÄ±n | Sohbet Â· mesaj Â· toplam jeton Â· **tahmini maliyet**. Maliyet, model fiyat tablosundan hesaplanÄ±r; sabit bir sayÄ± deÄŸildir |
| **2** | "PDO ile hazÄ±r ifadeler" sohbetini **AÃ§** | ÃœÃ§ soru-cevap. KullanÄ±cÄ± mesajlarÄ± saÄŸda mavi, yanÄ±tlar solda; kod Ã¶rnekleri girintisi korunarak basÄ±lÄ±r |
| **3** | Her yanÄ±tÄ±n altÄ±ndaki **jeton satÄ±rÄ±na** bakÄ±n | `412 giriÅŸ Â· 386 Ã§Ä±kÄ±ÅŸ jetonu Â· $0,011710`. Bu rakam uydurma deÄŸil: `giriÅŸ/1M Ã— 5$ + Ã§Ä±kÄ±ÅŸ/1M Ã— 25$` |
| **4** | AynÄ± sohbette **giriÅŸ jetonlarÄ±nÄ±n arttÄ±ÄŸÄ±nÄ±** izleyin: 412 â†’ 890 â†’ 1.503 | Model durum tutmaz; her istekte sohbetin **tamamÄ±** yeniden gÃ¶nderilir. Uzun sohbetlerin pahalÄ±laÅŸmasÄ±nÄ±n sebebi tam olarak budur |
| **5** | Sohbet baÅŸlÄ±ÄŸÄ±ndaki rozete bakÄ±n: `3.977 jeton Â· $0,04333` | Sohbet toplamÄ±, mesaj toplamlarÄ±na **birebir eÅŸittir**. Sayfa kendi iÃ§inde Ã§eliÅŸmez |
| **6** | "N+1 sorgu problemi" sohbetini aÃ§Ä±p **"dÃ¼ÅŸÃ¼nme Ã¶zetini gÃ¶ster"**e basÄ±n | Modelin yanÄ±tÄ± kurmadan Ã¶nceki muhakemesi. `<details>` ile aÃ§Ä±lÄ±r â€” JavaScript gerekmez |
| **7** | Kontrol panelindeki **API Kurulumu** kartÄ±na bakÄ±n | AnahtarÄ±n tanÄ±mlÄ± olup olmadÄ±ÄŸÄ±, model, efor seviyesi ve uÃ§ nokta tek bakÄ±ÅŸta |
| **8** | AynÄ± kartta "Ä°stek **sunucudan** atÄ±lÄ±r" notunu okuyun | Anahtar tarayÄ±cÄ±ya **asla** gÃ¶nderilmez. AnahtarÄ± JavaScript'e koyup doÄŸrudan API'ye istek atmak, onu sayfayÄ± aÃ§an herkese vermektir |
| **9** | Bir sohbeti **Sil**e basÄ±n | Mesajlar `ON DELETE CASCADE` ile birlikte gider; yetim satÄ±r kalmaz. YalnÄ±zca **kendi** sohbetinizi silebilirsiniz |
| **10** | Telefonunuzdan aÃ§Ä±n | Balonlar geniÅŸler, sayaÃ§lar alt alta dizilir; sayfa gÃ¶vdesinde **yatay kaydÄ±rma yoktur** |

> **Demoda API anahtarÄ± yoktur** â€” bu yÃ¼zden yeni bir yanÄ±t Ã¼retilemez. Ekrandaki Ã¼Ã§ sohbet, arayÃ¼zÃ¼ dolu hÃ¢liyle gÃ¶stermek iÃ§in **elle yazÄ±lmÄ±ÅŸ** Ã¶rneklerdir; jeton ve maliyet sayÄ±larÄ± gerÃ§ek fiyat tablosuyla hesaplanmÄ±ÅŸtÄ±r. Kendi anahtarÄ±nÄ±zÄ± `.env` dosyasÄ±na ekleyince gerÃ§ek yanÄ±tlar gelmeye baÅŸlar.

#### Demo alanÄ± hakkÄ±nda bilinmesi gerekenler

| Konu | Durum |
|---|---|
| **Veriler** | `database.sql` iÃ§indeki **51 kullanÄ±cÄ± + 3 Ã¶rnek sohbet + 14 mesaj**. GerÃ§ek kiÅŸi verisi yoktur. |
| **API anahtarÄ±** | Demoda **yok**. Sohbet gÃ¶nderme kapalÄ±dÄ±r; var olan sohbetler okunabilir. |
| **Ã–rnek sohbetler** | GerÃ§ek API Ã§aÄŸrÄ±sÄ± deÄŸil, elle yazÄ±lmÄ±ÅŸ Ã¶rneklerdir. Jeton ve maliyet sayÄ±larÄ± fiyat tablosuyla **tutarlÄ±dÄ±r**. |
| **SÄ±fÄ±rlama** | Demo veritabanÄ± **dÃ¼zenli aralÄ±klarla** baÅŸlangÄ±Ã§ hÃ¢line dÃ¶ner. |
| **`APP_DEBUG`** | CanlÄ±da **kendiliÄŸinden `false`** â€” sunucu adÄ±ndan tÃ¼retilir. |
| **BaÄŸÄ±mlÄ±lÄ±k** | **SÄ±fÄ±r.** SDK yok, Composer yok, npm yok, CDN yok. Ä°stek `cURL` ile atÄ±lÄ±r. |

---

### Bu Proje Nedir?

Bir yapay zekÃ¢ API'sini projeye baÄŸlamak, ilk bakÄ±ÅŸta tek bir `curl` Ã§aÄŸrÄ±sÄ±dÄ±r. GerÃ§ekte dÃ¶rt soru hemen ardÄ±ndan gelir ve dÃ¶rdÃ¼ de hafife alÄ±nÄ±rsa pahalÄ±ya patlar:

- **Anahtar nerede duracak?** JavaScript'e koyarsanÄ±z, sayfayÄ± aÃ§an herkes onu gÃ¶rÃ¼r ve sizin hesabÄ±nÄ±za istek atabilir.
- **Bu ay ne kadar harcadÄ±m?** Fatura ayÄ±n sonunda gelir; o zamana kadar hiÃ§bir fikriniz yoktur.
- **Neden ikinci soru birinciden pahalÄ±?** Ã‡Ã¼nkÃ¼ model durum tutmaz: her istekte sohbetin tamamÄ± yeniden gÃ¶nderilir ve **yeniden Ã¼cretlendirilir**.
- **API hata verdiÄŸinde ne olacak?** `429` ve `529` geÃ§icidir, tekrar denenmelidir; `401` kalÄ±cÄ±dÄ±r, denemenin anlamÄ± yoktur. Ä°kisini ayÄ±rt etmeyen kod ya boÅŸuna uÄŸraÅŸÄ±r ya da erken pes eder.

Bu proje dÃ¶rdÃ¼nÃ¼ de ele alan bir entegrasyon katmanÄ± kuruyor. Anahtar `.env` iÃ§inde durur ve **yalnÄ±zca sunucuda** kullanÄ±lÄ±r. Her yanÄ±tÄ±n giriÅŸ/Ã§Ä±kÄ±ÅŸ jetonu ve **hesaplanmÄ±ÅŸ maliyeti** kaydedilir. Sohbet geÃ§miÅŸi veritabanÄ±ndadÄ±r. Hata yÃ¶netimi geÃ§ici ile kalÄ±cÄ±yÄ± ayÄ±rÄ±r ve geÃ§ici olanlarÄ± **Ã¼stel geri Ã§ekilmeyle** yeniden dener.

Modelin "dÃ¼ÅŸÃ¼nme" Ã¶zeti de saklanÄ±r ve arayÃ¼zde istenirse aÃ§Ä±lÄ±r â€” yanÄ±tÄ±n nasÄ±l kurulduÄŸunu gÃ¶rmek, Ã§Ä±ktÄ±yÄ± deÄŸerlendirmenin en pratik yoludur.

SaÄŸlayÄ±cÄ± sÄ±nÄ±flarÄ± hiÃ§bir SDK kullanmaz; istek `cURL` ile atÄ±lÄ±r, yanÄ±t elle ayrÄ±ÅŸtÄ±rÄ±lÄ±r.

**Ve en Ã¶nemlisi: denemek iÃ§in para gerekmiyor.** VarsayÄ±lan saÄŸlayÄ±cÄ± Google Gemini'dir ve Ã¼cretsiz katmanÄ± vardÄ±r â€” [aistudio.google.com/apikey](https://aistudio.google.com/apikey) adresinden kredi kartÄ± vermeden, birkaÃ§ saniyede anahtar alÄ±rsÄ±nÄ±z.

**Kimler iÃ§in uygun?**

- Projesine yapay zekÃ¢ Ã¶zelliÄŸi ekleyecek, ama maliyeti kontrol altÄ±nda tutmak isteyenler
- API anahtarÄ±nÄ± nereye koyacaÄŸÄ±nÄ± soran herkes
- Jeton muhasebesinin nasÄ±l yapÄ±ldÄ±ÄŸÄ±nÄ± Ã¶ÄŸrenmek isteyenler
- SDK kurmadan, saf PHP ile bir yapay zekÃ¢ API'sine baÄŸlanmak isteyenler
- SaÄŸlayÄ±cÄ±ya kilitlenmeden, tek ayarla Gemini/Groq/Claude arasÄ±nda geÃ§iÅŸ yapmak isteyenler
- Bootstrap 5 Ã¼zerine kurulu, tekrar kullanÄ±labilir bir panel kalÄ±bÄ± arayanlar

Bu proje, **[Ã‡Ä±lgÄ±n YazÄ±lÄ±m KÃ¼tÃ¼phanesi](https://cilginyazilim.com/kutuphane)** altÄ±nda yayÄ±nlanan aÃ§Ä±klamalÄ±, Ã¼retime hazÄ±r Ã¶rneklerden biridir.

---

### Ä°Ã§indekiler

- [CanlÄ± Demo](#canlÄ±-demo)
- [Bu Proje Nedir?](#bu-proje-nedir)
- [Ekran GÃ¶rÃ¼ntÃ¼leri](#ekran-gÃ¶rÃ¼ntÃ¼leri)
- [Bir isteÄŸin yolculuÄŸu](#bir-isteÄŸin-yolculuÄŸu)
- [Kritik Kararlar](#kritik-kararlar)
- [Neler Var?](#neler-var)
- [Maliyet nasÄ±l hesaplanÄ±yor?](#maliyet-nasÄ±l-hesaplanÄ±yor)
- [Hata yÃ¶netimi](#hata-yÃ¶netimi)
- [GÃ¼venlik: Neyi, NasÄ±l KapattÄ±k?](#gÃ¼venlik-neyi-nasÄ±l-kapattÄ±k)
- [Kurulum](#kurulum)
- [YapÄ±landÄ±rma](#yapÄ±landÄ±rma)
- [SaÄŸlayÄ±cÄ± seÃ§mek](#saÄŸlayÄ±cÄ±-seÃ§mek)
- [Dosya YapÄ±sÄ±](#dosya-yapÄ±sÄ±)
- [VeritabanÄ± ÅžemasÄ±](#veritabanÄ±-ÅŸemasÄ±)
- [SSS](#sss)
- [CanlÄ± Ortama AlÄ±rken](#canlÄ±-ortama-alÄ±rken)
- [Sorun Giderme](#sorun-giderme)
- [Yol HaritasÄ±](#yol-haritasÄ±)
- [KatkÄ±](#katkÄ±)
- [Lisans](#lisans)

---

### Ekran GÃ¶rÃ¼ntÃ¼leri

#### Sohbetler

DÃ¶rt sayaÃ§ jeton muhasebesinin Ã¶zetidir: sohbet Â· mesaj Â· toplam jeton Â· **tahmini maliyet**. Maliyet sabit bir sayÄ± deÄŸil, model fiyat tablosundan hesaplanÄ±r (`giriÅŸ/1M Ã— 5$ + Ã§Ä±kÄ±ÅŸ/1M Ã— 25$`). Her sohbet satÄ±rÄ± kendi jeton ve maliyet rozetini taÅŸÄ±r.

![Sohbet listesi: sohbet, mesaj, jeton ve tahmini maliyet sayaÃ§larÄ±](docs/screenshots/03-sohbetler.png)

#### Sohbet detayÄ±

KullanÄ±cÄ± mesajlarÄ± saÄŸda, yanÄ±tlar solda; kod Ã¶rnekleri girintisi korunarak basÄ±lÄ±r. Her yanÄ±tÄ±n altÄ±ndaki satÄ±r o mesajÄ±n giriÅŸ/Ã§Ä±kÄ±ÅŸ jetonunu ve maliyetini verir. GiriÅŸ jetonlarÄ±nÄ±n mesaj mesaj artÄ±ÅŸÄ± (412 â†’ 890 â†’ 1.503) burada gÃ¶zle gÃ¶rÃ¼lÃ¼r: model durum tutmaz, her istekte sohbetin **tamamÄ±** yeniden gÃ¶nderilir ve yeniden Ã¼cretlendirilir. Modelin dÃ¼ÅŸÃ¼nme Ã¶zeti `<details>` ile aÃ§Ä±lÄ±r â€” JavaScript gerekmez.

![Sohbet detayÄ±: mesaj balonlarÄ±, mesaj baÅŸÄ±na jeton ve maliyet satÄ±rÄ±, aÃ§Ä±labilir dÃ¼ÅŸÃ¼nme Ã¶zeti](docs/screenshots/04-sohbet-detay.png)

#### Kontrol paneli

**API Kurulumu** kartÄ± anahtarÄ±n tanÄ±mlÄ± olup olmadÄ±ÄŸÄ±nÄ±, modeli, efor seviyesini ve uÃ§ noktayÄ± tek bakÄ±ÅŸta verir. KartÄ±n altÄ±ndaki not, isteÄŸin **sunucudan** atÄ±ldÄ±ÄŸÄ±nÄ± sÃ¶yler: anahtar tarayÄ±cÄ±ya asla gÃ¶nderilmez.

![Kontrol paneli: sayaÃ§ ÅŸeridi ve API kurulum kartÄ±](docs/screenshots/02-kontrol-paneli.png)

#### GiriÅŸ ekranÄ±

Demo hesaplarÄ± tek tÄ±kla doldurulur. GiriÅŸ denemeleri hÄ±z sÄ±nÄ±rÄ±na tabidir; art arda baÅŸarÄ±sÄ±z denemeden sonra hesap geÃ§ici olarak kilitlenir.

![GiriÅŸ ekranÄ±: demo hesaplarÄ± tek tÄ±kla doldurulur](docs/screenshots/01-giris.png)

#### Koyu tema

Tema tarayÄ±cÄ±da deÄŸil **kullanÄ±cÄ± hesabÄ±nda** saklanÄ±r; baÅŸka bir cihazdan girdiÄŸinizde de aynÄ± gelir. Sohbet balonlarÄ±nÄ±n zemin ve metin renkleri koyu temada ayrÄ±ca Ã¶lÃ§Ã¼lÃ¼dÃ¼r.

![Koyu tema gÃ¶rÃ¼nÃ¼mÃ¼](docs/screenshots/05-koyu-tema.png)

#### Mobil gÃ¶rÃ¼nÃ¼m

390px geniÅŸlikte balonlar geniÅŸler, sayaÃ§lar alt alta dizilir ve alt navigasyon devreye girer. Sayfa gÃ¶vdesinde yatay kaydÄ±rma yoktur.

<img src="docs/screenshots/06-mobil.png" alt="390px geniÅŸlikte mobil gÃ¶rÃ¼nÃ¼m" width="360">

---

### Bir isteÄŸin yolculuÄŸu

```
 TARAYICI                          SUNUCU (PHP)                    SAÄžLAYICI API
 â”€â”€â”€â”€â”€â”€â”€â”€                          â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€                    â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
 KullanÄ±cÄ± mesajÄ± yazar
    â”‚  POST /api/chat/send
    â”‚  (CSRF jetonu ile)
    â–¼
                          ai_messages'a "user" satÄ±rÄ±
                                   â”‚
                                   â”‚  Ai::fromEnv()->send()
                                   â”‚  (gemini Â· groq Â· claude â€¦)
                                   â”‚
                                   â”‚  1) SOHBETÄ°N TAMAMINI topla
                                   â”‚     (model durum tutmaz)
                                   â”‚
                                   â”‚  2) x-goog-api-key: <ANAHTAR> â—„â”€ ANAHTAR
                                   â”‚     (Claude'da x-api-key)        BURADA KALIR
                                   â”‚                                  tarayÄ±cÄ±ya
                                   â”‚  3) POST â€¦:generateContent â”€â”€â”€â”€â”€â”€â–º GÄ°TMEZ
                                   â”‚                                     â”‚
                                   â”‚                                     â–¼
                                   â”‚  â—„â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ 200 / 429 / 529 / 4xx
                                   â”‚
                                   â”‚  4) 429 Â· 529 Â· 5xx  â†’ GEÃ‡Ä°CÄ°
                                   â”‚     Ã¼stel geri Ã§ekilme + jitter
                                   â”‚     en fazla 3 kez yeniden dene
                                   â”‚
                                   â”‚     401 Â· 400        â†’ KALICI
                                   â”‚     denemeden vazgeÃ§, aÃ§Ä±kla
                                   â”‚
                                   â”‚  5) YanÄ±tÄ± ayrÄ±ÅŸtÄ±r:
                                   â”‚     text Â· thinking Â· stop_reason
                                   â”‚     refusal Â· usage
                                   â”‚
                                   â”‚  6) MALÄ°YET HESAPLA
                                   â”‚     giriÅŸ/1MÃ—5$ + Ã§Ä±kÄ±ÅŸ/1MÃ—25$
                                   â–¼
                          ai_messages'a "assistant" satÄ±rÄ±
                          (metin Â· dÃ¼ÅŸÃ¼nme Â· jetonlar Â· maliyet)
                                   â”‚
                          ai_conversations toplamlarÄ± gÃ¼ncellenir
                                   â”‚
    â—„â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ JSON yanÄ±t
    â–¼
 Balon Ã§izilir, jeton satÄ±rÄ± basÄ±lÄ±r
```

---

### Kritik Kararlar

#### 1. API anahtarÄ± **asla** tarayÄ±cÄ±ya gitmez

Ä°nternetteki Ã¶rneklerin ÅŸaÅŸÄ±rtÄ±cÄ± bir kÄ±smÄ± anahtarÄ± JavaScript'e koyar ve `fetch` ile doÄŸrudan API'ye gider. Bu, anahtarÄ± **sayfayÄ± aÃ§an herkese vermektir**: `F12 â†’ Sources` yeterlidir. AnahtarÄ±nÄ±zla baÅŸkalarÄ± istek atar, faturayÄ± siz Ã¶dersiniz.

Bu projede istek **her zaman sunucudan** atÄ±lÄ±r:

```
TarayÄ±cÄ± â†’ (kendi sunucunuz) â†’ SaÄŸlayÄ±cÄ± API
```

Anahtar `.env` dosyasÄ±ndadÄ±r, `.gitignore` iÃ§indedir ve PHP dÄ±ÅŸÄ±na hiÃ§ Ã§Ä±kmaz. TarayÄ±cÄ± yalnÄ±zca kendi sunucunuzla konuÅŸur â€” CSRF korumalÄ±, oturum gerektiren bir uÃ§ nokta Ã¼zerinden.

#### 2. Her mesajÄ±n jetonu ve maliyeti **kaydedilir**

Fatura ayÄ±n sonunda gelir. O zamana kadar hangi Ã¶zelliÄŸin ne kadar harcadÄ±ÄŸÄ±nÄ± bilmiyorsanÄ±z, maliyeti yÃ¶netemezsiniz.

```sql
ai_messages: input_tokens Â· output_tokens Â· cost_usd
ai_conversations: total_tokens Â· total_cost
```

SayÄ±lar API'nin `usage` alanÄ±ndan gelir â€” tahmin deÄŸil, Ã¶lÃ§Ã¼mdÃ¼r. Maliyet ise fiyat tablosundan hesaplanÄ±r.

Sohbet satÄ±rÄ±ndaki toplam, mesajlarÄ±n toplamÄ±na **eÅŸittir**; iki yerde tutulan bir sayÄ±nÄ±n tutarsÄ±z kalmasÄ±, gÃ¼venilmez bir gÃ¶sterge demektir.

#### 3. GiriÅŸ jetonu neden her mesajda artÄ±yor?

Ã‡Ã¼nkÃ¼ **model durum tutmaz**. "Ã–nceki mesajÄ±mÄ± hatÄ±rla" diye bir ÅŸey yoktur; her istekte sohbetin tamamÄ±nÄ± yeniden gÃ¶nderirsiniz ve tamamÄ± yeniden Ã¼cretlendirilir.

Ã–rnek sohbette bunu somut gÃ¶rÃ¼rsÃ¼nÃ¼z: `412 â†’ 890 â†’ 1.503`. ÃœÃ§Ã¼ncÃ¼ soru, birincinin dÃ¶rt katÄ± giriÅŸ jetonu tÃ¼ketir â€” soru aynÄ± uzunlukta olsa bile.

Bu, uzun sohbetlerin neden pahalÄ±laÅŸtÄ±ÄŸÄ±nÄ± aÃ§Ä±klar. Pratik sonuÃ§: geÃ§miÅŸi sÄ±nÄ±rsÄ±z gÃ¶ndermeyin. Uzun sohbetlerde eski mesajlarÄ± Ã¶zetleyip Ã¶zeti gÃ¶ndermek yaygÄ±n ve etkili bir kalÄ±ptÄ±r.

#### 4. GeÃ§ici hata ile kalÄ±cÄ± hata ayrÄ±lÄ±r

```php
$retryable = $status === 429 || $status === 529 || $status >= 500;
```

| Kod | AnlamÄ± | Ne yapÄ±lÄ±r |
|---|---|---|
| `429` | HÄ±z sÄ±nÄ±rÄ± | **GeÃ§ici** â€” geri Ã§ekilmeyle yeniden dene |
| `529` | Servis yoÄŸun | **GeÃ§ici** â€” yeniden dene |
| `5xx` | Sunucu hatasÄ± | **GeÃ§ici** â€” yeniden dene |
| `401` | Anahtar geÃ§ersiz | **KalÄ±cÄ±** â€” denemenin anlamÄ± yok |
| `400` | Ä°stek hatalÄ± | **KalÄ±cÄ±** â€” istek dÃ¼zeltilmeli |

AyrÄ±m yapmayan kod iki yÃ¶nden de kaybeder: `401` iÃ§in Ã¼Ã§ kez deneyip zaman kaybeder, `429` iÃ§in hiÃ§ denemeyip kullanÄ±cÄ±ya gereksiz hata gÃ¶sterir.

Yeniden denemeler **Ã¼stel geri Ã§ekilme + jitter** ile yapÄ±lÄ±r. Jitter (rastgele sapma) Ã¶nemlidir: aynÄ± anda sÄ±nÄ±ra Ã§arpan yÃ¼z istemci aynÄ± anda tekrar denerse sÄ±nÄ±ra yine birlikte Ã§arparlar.

#### 5. `stop_reason` ve `refusal` gÃ¶z ardÄ± edilmez

Bir yanÄ±t "baÅŸarÄ±lÄ±" dÃ¶nebilir ama **tamamlanmamÄ±ÅŸ** olabilir:

- `stop_reason = "max_tokens"` â†’ yanÄ±t cÃ¼mlenin ortasÄ±nda kesildi. KullanÄ±cÄ±ya eksik bir metni tam gibi gÃ¶stermek yanlÄ±ÅŸtÄ±r.
- `refusal` dolu â†’ model bilerek yanÄ±tlamadÄ±. Bu bir hata deÄŸildir ve "sunucu hatasÄ±" diye gÃ¶sterilmemelidir.

Ä°kisi de ayrÄ± ele alÄ±nÄ±r ve arayÃ¼zde ayrÄ± biÃ§imde gÃ¶sterilir.

`AI_MAX_TOKENS` varsayÄ±lanÄ± bu yÃ¼zden **16.000**'dir. DÃ¼ÅŸÃ¼k tutmak tasarruf gibi gÃ¶rÃ¼nÃ¼r ama kesilen yanÄ±tÄ± baÅŸtan sormak zorunda kalÄ±rsÄ±nÄ±z â€” yani iki kez Ã¶dersiniz.

#### 6. "DÃ¼ÅŸÃ¼nme" Ã¶zeti saklanÄ±r, ama gizlenerek gÃ¶sterilir

Modelin muhakemesi, Ã§Ä±ktÄ±yÄ± deÄŸerlendirmenin en pratik yoludur: yanÄ±t yanlÄ±ÅŸsa nerede saptÄ±ÄŸÄ±nÄ± gÃ¶rÃ¼rsÃ¼nÃ¼z.

Ama her zaman ekranda durmasÄ± gerekmez; `<details>` etiketiyle katlanÄ±r. JavaScript gerekmez, eriÅŸilebilirlik kendiliÄŸinden doÄŸrudur.

#### 7. Metin `pre-wrap` ile basÄ±lÄ±r, `nl2br()` ile deÄŸil

Model yanÄ±tlarÄ± kod Ã¶rneÄŸi iÃ§erir ve kodun **girintisi** anlamlÄ±dÄ±r.

```css
.cy-msg__bubble { white-space: pre-wrap; }
```

`pre-wrap` hem satÄ±r sonlarÄ±nÄ± hem girintileri korur, uzun satÄ±rlarÄ± da kÄ±rar. ÃœstÃ¼ne `nl2br()` eklemek her satÄ±r sonunu **iki kez** uygular ve paragraf aralarÄ± iki katÄ±na Ã§Ä±kar â€” kod iÃ§eren yanÄ±tlarda ekran daÄŸÄ±lÄ±r.

> AynÄ± sebeple balonun `<div>` etiketiyle iÃ§eriÄŸi arasÄ±nda **boÅŸluk bÄ±rakÄ±lmaz**: `pre-wrap`, ÅŸablonun kendi girintisini de metin sayar ve her balonun ilk satÄ±rÄ± saÄŸa kaymÄ±ÅŸ gÃ¶rÃ¼nÃ¼rdÃ¼.

#### 8. Sohbet silinince mesajlar da gider

```sql
CONSTRAINT fk_msg_conv FOREIGN KEY (conversation_id)
    REFERENCES ai_conversations (id) ON DELETE CASCADE
```

Uygulama kodunda "Ã¶nce mesajlarÄ± sil, sonra sohbeti sil" yazÄ±lsaydÄ±, o iki adÄ±mÄ±n arasÄ±nda bir hata oluÅŸtuÄŸunda yetim mesajlar kalÄ±rdÄ±. KÄ±sÄ±tÄ± veritabanÄ±na koymak bunu **imkÃ¢nsÄ±z** kÄ±lar.

---

### Neler Var?

<tr><td valign="top" width="50%">

**API katmanÄ±**

- Messages API'sine `cURL` ile istek â€” **SDK yok**
- Anahtar yalnÄ±zca sunucuda
- Ãœstel geri Ã§ekilme + jitter, en fazla 3 deneme
- GeÃ§ici (`429`/`529`/`5xx`) ve kalÄ±cÄ± hata ayrÄ±mÄ±
- `stop_reason` ve `refusal` ayrÄ± ele alÄ±nÄ±r
- Model ve efor seviyesi `.env`'den
- YapÄ±landÄ±rÄ±labilir `max_tokens`

**Muhasebe**

- Mesaj baÅŸÄ±na giriÅŸ/Ã§Ä±kÄ±ÅŸ jetonu
- Mesaj baÅŸÄ±na maliyet (fiyat tablosundan)
- Sohbet baÅŸÄ±na toplam jeton ve maliyet
- Panelde dÃ¶rt sayaÃ§

</td><td valign="top" width="50%">

**Sohbet arayÃ¼zÃ¼**

- Sohbet listesi, jeton ve maliyet sÃ¼tunlu
- KullanÄ±cÄ±/model balonlarÄ±, kod girintisi korunur
- Katlanabilir "dÃ¼ÅŸÃ¼nme Ã¶zeti" (`<details>`)
- Mesaj altÄ±nda jeton ve maliyet satÄ±rÄ±
- Sohbet silme (yalnÄ±zca kendi sohbeti)
- Anahtar yoksa aÃ§Ä±klayÄ±cÄ± uyarÄ±

**Ortak altyapÄ±**

- Oturum giriÅŸi, "beni hatÄ±rla", hÄ±z sÄ±nÄ±rÄ±, CSRF
- CSP (`script-src 'self'`), `X-Frame-Options: DENY`
- AÃ§Ä±k / koyu tema, hesaba kayÄ±tlÄ±
- Mobilde alt navigasyon, yatay kaydÄ±rma yok
- KullanÄ±cÄ±lar sayfasÄ±nda canlÄ± filtre (JS kapalÄ±ysa da Ã§alÄ±ÅŸÄ±r)

</td></tr>

---

### Maliyet nasÄ±l hesaplanÄ±yor?

Fiyatlar milyon jeton baÅŸÄ±nadÄ±r ve her saÄŸlayÄ±cÄ±nÄ±n kendi `PRICING` tablosundadÄ±r. **Ãœcretsiz katmanda gerÃ§ek maliyetiniz sÄ±fÄ±rdÄ±r**; rakam yine de gÃ¶sterilir, Ã§Ã¼nkÃ¼ asÄ±l soru "bugÃ¼n ne Ã¶dedim?" deÄŸil, "bu uygulama yayÄ±na Ã§Ä±karsa ne Ã¶derim?" sorusudur.

`GeminiProvider::PRICING` â€” Ã¼cretli katman:

| Model | GiriÅŸ | Ã‡Ä±kÄ±ÅŸ |
|---|---|---|
| `gemini-2.5-flash-lite` | 0,10 $ | 0,40 $ |
| `gemini-2.5-flash` | 0,30 $ | 2,50 $ |
| `gemini-3.8-flash` | 0,75 $ | 3,75 $ |

`ClaudeProvider::PRICING`:

| Model | GiriÅŸ (1M jeton) | Ã‡Ä±kÄ±ÅŸ (1M jeton) |
|---|---|---|
| `claude-opus-5` | 5,00 $ | 25,00 $ |
| `claude-sonnet-5` | 2,00 $ | 10,00 $ |
| `claude-haiku-4-5` | 1,00 $ | 5,00 $ |

```php
public static function estimateCost(string $model, array $usage): float
{
    $rates = self::PRICING[$model] ?? null;
    if ($rates === null) { return 0.0; }

    return ($usage['input_tokens']  / 1000000) * $rates['input']
         + ($usage['output_tokens'] / 1000000) * $rates['output'];
}
```

Ã–rnek: 412 giriÅŸ + 386 Ã§Ä±kÄ±ÅŸ jetonu â†’

```
412 / 1.000.000 Ã— 5  = 0,00206
386 / 1.000.000 Ã— 25 = 0,00965
                       â”€â”€â”€â”€â”€â”€â”€â”€â”€
                       0,01171 $
```

Demodaki sohbetlerde bu hesabÄ± satÄ±r satÄ±r doÄŸrulayabilirsiniz.

> **Bu bir tahmindir, fatura deÄŸildir.** Fiyatlar koda gÃ¶mÃ¼lÃ¼dÃ¼r ve deÄŸiÅŸebilir; ayrÄ±ca Ã¶n belleÄŸe **yazÄ±lan** ve Ã¶n bellekten **okunan** jetonlar farklÄ± oranlarla Ã¼cretlendirilir â€” burada yalnÄ±zca normal giriÅŸ ve Ã§Ä±kÄ±ÅŸ hesaba katÄ±lÄ±r. Yine de bÃ¼yÃ¼klÃ¼k mertebesini gÃ¶rmek Ã§ok deÄŸerlidir: "bu sohbet 0,04 dolar" bilgisi, model veya efor seviyesi deÄŸiÅŸtirme kararÄ±nÄ± somut hÃ¢le getirir.

TanÄ±mlÄ± olmayan bir model adÄ± iÃ§in `0.0` dÃ¶ner â€” yanlÄ±ÅŸ bir rakam gÃ¶stermektense hiÃ§ gÃ¶stermemek yeÄŸdir.

---

### Hata yÃ¶netimi

SaÄŸlayÄ±cÄ±nÄ±n `send()` metodu her durumda **anlaÅŸÄ±lÄ±r** bir sonuÃ§ dÃ¶ndÃ¼rÃ¼r; ham bir istisna arayÃ¼ze sÄ±zmaz.

| Durum | KullanÄ±cÄ± ne gÃ¶rÃ¼r |
|---|---|
| Anahtar tanÄ±msÄ±z | "API anahtarÄ± tanÄ±mlÄ± deÄŸil" + `.env` satÄ±rÄ± |
| `401` | "Anahtar geÃ§ersiz" â€” yeniden denenmez |
| `429` (3 denemeden sonra) | "HÄ±z sÄ±nÄ±rÄ±na takÄ±ldÄ±nÄ±z ve yeniden denemeler de yetmedi." |
| `529` / `5xx` | "Servis geÃ§ici olarak yoÄŸun" |
| `stop_reason = max_tokens` | YanÄ±t gÃ¶sterilir + **kesildiÄŸi** belirtilir |
| `refusal` dolu | Modelin yanÄ±tlamama gerekÃ§esi, hata olarak deÄŸil |
| AÄŸ hatasÄ± / zaman aÅŸÄ±mÄ± | Geri Ã§ekilmeyle yeniden denenir, sonra aÃ§Ä±klanÄ±r |

---

### GÃ¼venlik: Neyi, NasÄ±l KapattÄ±k?

| AÃ§Ä±k | Tipik hatalÄ± kod | Bu projede |
|---|---|---|
| **API anahtarÄ± sÄ±zÄ±ntÄ±sÄ±** | AnahtarÄ± JavaScript'e koyup tarayÄ±cÄ±dan istek atmak | Ä°stek **yalnÄ±zca sunucudan**; anahtar `.env` iÃ§inde, `.gitignore`'da |
| **AnahtarÄ±n depoya gitmesi** | `config.php` iÃ§ine yazmak | `.env` dosyasÄ± depoya **gÃ¶nderilmez**; `.env.example` ÅŸablondur |
| **BaÅŸkasÄ±nÄ±n sohbetini okuma (IDOR)** | `WHERE id = :id` | Sorguya `user_id` de katÄ±lÄ±r; kullanÄ±cÄ± yalnÄ±zca **kendi** sohbetini gÃ¶rÃ¼r ve siler |
| **Yetim kayÄ±t** | Uygulama kodunda iki adÄ±mlÄ± silme | `ON DELETE CASCADE` â€” veritabanÄ± garanti eder |
| **Sonsuz maliyet** | `max_tokens` sÄ±nÄ±rsÄ±z / geÃ§miÅŸ sÄ±nÄ±rsÄ±z | `AI_MAX_TOKENS` ayarlanabilir; jeton ve maliyet **her mesajda** kaydedilir |
| **BoÅŸuna yeniden deneme** | Her hatada 3 kez denemek | `401`/`400` **kalÄ±cÄ±** sayÄ±lÄ±r, denenmez |
| **EÅŸzamanlÄ± yeniden deneme fÄ±rtÄ±nasÄ±** | Sabit aralÄ±klÄ± tekrar | Ãœstel geri Ã§ekilme + **jitter** |
| **XSS** | `echo $message['content']` | Sunucuda `e()`; ayrÄ±ca CSP `script-src 'self'` |
| **CSRF** | Gizli alan yok | Her POST'ta jeton; `hash_equals()` |
| **SQL enjeksiyonu** | `"... WHERE id = $id"` | TÃ¼m sorgular hazÄ±r ifade; `ATTR_EMULATE_PREPARES = false` |
| **Hata sÄ±zÄ±ntÄ±sÄ±** | Ä°stisna mesajÄ±nÄ± ekrana basmak | `APP_DEBUG` **ortamdan tÃ¼retilir**; canlÄ±da ayrÄ±ntÄ± gÃ¶sterilmez |
| **Bozuk UTF-8'de sessiz JSON kaybÄ±** | `json_encode($v)` | `JSON_INVALID_UTF8_SUBSTITUTE` |

---

### Kurulum

#### Gereksinimler

| | |
|---|---|
| PHP | 8.0 veya Ã¼zeri Â· **`curl` eklentisi zorunlu** |
| MySQL / MariaDB | 5.7+ / 10.3+ |
| Web sunucusu | Apache (`mod_rewrite`) veya Nginx |
| Bir API anahtarÄ± | **Ãœcretsiz:** [aistudio.google.com/apikey](https://aistudio.google.com/apikey) (Gemini) veya [console.groq.com/keys](https://console.groq.com/keys) (Groq) |

#### AdÄ±mlar

```bash
git clone https://github.com/CilginYazilim/ai-integration-system.git
cd ai-integration-system

mysql -u root -p < database.sql
cp .env.example .env        # Windows: copy .env.example .env
```

`.env` dosyasÄ±na **Ã¼cretsiz** anahtarÄ±nÄ±zÄ± ekleyin:

```env
AI_PROVIDER=gemini
GEMINI_API_KEY=â€¢â€¢â€¢â€¢â€¢â€¢â€¢â€¢
```

> AnahtarÄ± [aistudio.google.com/apikey](https://aistudio.google.com/apikey) adresinden
> alÄ±rsÄ±nÄ±z: Google hesabÄ±yla girin, **Create API key**, kopyalayÄ±n. Kredi kartÄ±
> istenmez, faturalandÄ±rma aÃ§manÄ±z gerekmez.

AÃ§Ä±n: `http://localhost/ai-integration-system/` Â· GiriÅŸ: `admin@cilginyazilim.com` / `Admin1234`

> **Anahtar olmadan da aÃ§Ä±lÄ±r.** Var olan sohbetleri okuyabilir, arayÃ¼zÃ¼ inceleyebilirsiniz; yalnÄ±zca yeni yanÄ±t Ã¼retilemez. Panel bunu aÃ§Ä±kÃ§a sÃ¶yler.

---

### YapÄ±landÄ±rma

```env
APP_DEBUG=true          # silerseniz: yerelde aÃ§Ä±k, canlÄ±da kapalÄ±
APP_URL=
APP_PRETTY_URLS=true

DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=cy_ai
DB_USER=root
DB_PASS=

# --- YAPAY ZEKÃ‚ SAÄžLAYICISI ---
AI_PROVIDER=gemini
GEMINI_API_KEY=
â€¢â€¢â€¢â€¢â€¢â€¢â€¢â€¢
AI_MAX_TOKENS=â€¢â€¢â€¢â€¢â€¢â€¢â€¢â€¢
```

| Ayar | Ne yapar |
|---|---|
| `AI_PROVIDER` | `gemini` Â· `groq` Â· `openai-compatible` Â· `claude`. VarsayÄ±lan `gemini` |
| `AI_MODEL` | KullanÄ±lacak model. BoÅŸ bÄ±rakÄ±rsanÄ±z saÄŸlayÄ±cÄ±nÄ±n varsayÄ±lanÄ± kullanÄ±lÄ±r |
| `AI_MAX_TOKENS` | YanÄ±tÄ±n en fazla kaÃ§ jeton olacaÄŸÄ±. **DÃ¼ÅŸÃ¼k tutmayÄ±n**: sÄ±nÄ±ra Ã§arpan yanÄ±t cÃ¼mlenin ortasÄ±nda kesilir ve baÅŸtan sormanÄ±z gerekir |
| `AI_BASE_URL` | YalnÄ±zca `openai-compatible` iÃ§in: hangi servise baÄŸlanÄ±lacaÄŸÄ± |
| `AI_THINKING` | Gemini'de dÃ¼ÅŸÃ¼nme Ã¶zeti istensin mi (varsayÄ±lan kapalÄ±) |
| `AI_EFFORT` | Claude'da dÃ¼ÅŸÃ¼nme derinliÄŸi. YÃ¼kseltmek daha iyi yanÄ±t verir ama hem sÃ¼reyi hem maliyeti artÄ±rÄ±r |

#### SaÄŸlayÄ±cÄ± seÃ§mek

Uygulama saÄŸlayÄ±cÄ±yÄ± **bilmez**. `App\Core\Ai\Ai::fromEnv()` ayara bakÄ±p doÄŸru
sÄ±nÄ±fÄ± Ã¼retir; denetleyici ve arayÃ¼z aynÄ± kalÄ±r. SaÄŸlayÄ±cÄ± deÄŸiÅŸtirmek Ã¼Ã§ satÄ±rdÄ±r:

| SaÄŸlayÄ±cÄ± | `.env` | Ãœcretsiz katman | Anahtar |
|---|---|---|---|
| **Google Gemini** *(varsayÄ±lan)* | `AI_PROVIDER=gemini`<br>`GEMINI_API_KEY=â€¦`<br>`AI_MODEL=gemini-2.5-flash` | **var** | [aistudio.google.com/apikey](https://aistudio.google.com/apikey) |
| **Groq** | `AI_PROVIDER=groq`<br>`GROQ_API_KEY=â€¦`<br>`AI_MODEL=llama-3.3-70b-versatile` | **var** | [console.groq.com/keys](https://console.groq.com/keys) |
| **xAI (Grok) Â· OpenRouter Â· Ollama** | `AI_PROVIDER=openai-compatible`<br>`AI_API_KEY=â€¦`<br>`AI_BASE_URL=https://api.x.ai/v1` | saÄŸlayÄ±cÄ±ya gÃ¶re | saÄŸlayÄ±cÄ±nÄ±n paneli |
| **Anthropic Claude** | `AI_PROVIDER=claude`<br>`ANTHROPIC_API_KEY=â€¦`<br>`AI_MODEL=claude-sonnet-5` | yok (Ã¼cretli) | [console.anthropic.com](https://console.anthropic.com) |

**Neden varsayÄ±lan Ã¼cretsiz bir saÄŸlayÄ±cÄ±?** Bu bir Ã¶ÄŸrenme Ã¶rneÄŸidir ve Ã¶nÃ¼ndeki en
pahalÄ± engel kredi kartÄ±ydÄ±: kodu okumak isteyen Ã§oÄŸu kiÅŸi Ã§alÄ±ÅŸÄ±r hÃ¢lini hiÃ§
gÃ¶rmeden ayrÄ±lÄ±yordu.

**Yeni bir saÄŸlayÄ±cÄ± eklemek** `HttpProvider` sÄ±nÄ±fÄ±nÄ± geniÅŸletip dÃ¶rt soruyu
cevaplamaktÄ±r: nereye (`endpoint`), hangi baÅŸlÄ±kla (`headers`), hangi gÃ¶vdeyle
(`payload`), gelen yanÄ±t ortak biÃ§ime nasÄ±l Ã§evrilir (`normalize`). Yeniden deneme,
geri Ã§ekilme ve cURL ayarlarÄ± zaten ortak katmandadÄ±r.

---

### Dosya YapÄ±sÄ±

```
ai-integration-system/
â”‚
â”œâ”€â”€ index.php                     Ã–n denetleyici â€” TEK giriÅŸ noktasÄ±
â”œâ”€â”€ database.sql                  Åžema + 51 kullanÄ±cÄ± + 3 sohbet + 14 mesaj
â”œâ”€â”€ .env.example
â”‚
â”œâ”€â”€ app/
â”‚   â”œâ”€â”€ Core/
â”‚   â”‚   â”œâ”€â”€ Ai/                   â˜
 SAÄžLAYICI KATMANI
â”‚   â”‚   â”‚   â”œâ”€â”€ Ai.php                Fabrika â€” AI_PROVIDER'a bakar
â”‚   â”‚   â”‚   â”œâ”€â”€ Provider.php          ArayÃ¼z + ortak yanÄ±t sÃ¶zleÅŸmesi
â”‚   â”‚   â”‚   â”œâ”€â”€ HttpProvider.php      cURL Â· yeniden deneme Â· geri Ã§ekilme
â”‚   â”‚   â”‚   â”œâ”€â”€ GeminiProvider.php    VarsayÄ±lan â€” Ã¼cretsiz katman
â”‚   â”‚   â”‚   â”œâ”€â”€ OpenAiCompatibleProvider.php  Groq Â· xAI Â· OpenRouter Â· Ollama
â”‚   â”‚   â”‚   â””â”€â”€ ClaudeProvider.php    Anthropic Messages API
â”‚   â”‚   â”œâ”€â”€ Auth.php Â· Session.php Â· Csrf.php Â· RateLimiter.php
â”‚   â”‚   â”œâ”€â”€ Database.php          PDO (EMULATE_PREPARES = false)
â”‚   â”‚   â”œâ”€â”€ Env.php               .env okuyucu + isLocalHost()
â”‚   â”‚   â””â”€â”€ ...
â”‚   â”‚
â”‚   â”œâ”€â”€ Http/Controllers/
â”‚   â”‚   â”œâ”€â”€ ChatController.php    Sohbet listesi, detay, silme
â”‚   â”‚   â”œâ”€â”€ Api/ChatApiController.php   Mesaj gÃ¶nderme (AJAX)
â”‚   â”‚   â””â”€â”€ Auth Â· Dashboard Â· User
â”‚   â”‚
â”‚   â”œâ”€â”€ Repositories/ConversationRepository.php
â”‚   â””â”€â”€ Support/helpers.php
â”‚
â”œâ”€â”€ views/
â”‚   â”œâ”€â”€ chat/index.php            Sohbet listesi + sayaÃ§lar
â”‚   â”œâ”€â”€ chat/show.php             â˜
 Balonlar Â· dÃ¼ÅŸÃ¼nme Ã¶zeti Â· jeton satÄ±rÄ±
â”‚   â””â”€â”€ ...
â”‚
â”œâ”€â”€ assets/
â”‚   â”œâ”€â”€ css/  cilginyazilim.css (marka) Â· admin.css Â· feature.css
â”‚   â””â”€â”€ js/   chat.js Â· app.js Â· login.js Â· users.js
â”‚
â”œâ”€â”€ config/config.php
â”œâ”€â”€ routes/web.php
â””â”€â”€ docs/screenshots/
```

---

### VeritabanÄ± ÅžemasÄ±

#### `ai_conversations`

| SÃ¼tun | Tip | Ä°ÅŸi |
|---|---|---|
| `id` | INT UNSIGNED | Birincil anahtar |
| `user_id` | INT UNSIGNED | Sohbet kimin (`ON DELETE CASCADE`) |
| `title` | VARCHAR(150) | Listede gÃ¶rÃ¼nen ad |
| `total_tokens` | INT UNSIGNED | GiriÅŸ + Ã§Ä±kÄ±ÅŸ toplamÄ± |
| `total_cost` | DECIMAL(12,8) | Toplam maliyet (USD) |
| `created_at` Â· `updated_at` | DATETIME | AÃ§Ä±lÄ±ÅŸ ve son mesaj anÄ± |

#### `ai_messages`

| SÃ¼tun | Tip | Ä°ÅŸi |
|---|---|---|
| `id` | BIGINT UNSIGNED | Birincil anahtar |
| `conversation_id` | INT UNSIGNED | Hangi sohbet (`ON DELETE CASCADE`) |
| `role` | ENUM('user','assistant') | Kim yazdÄ± |
| `content` | MEDIUMTEXT | Mesaj metni |
| `thinking` | MEDIUMTEXT NULL | Modelin muhakemesi (varsa) |
| `input_tokens` Â· `output_tokens` | INT UNSIGNED | API'nin `usage` alanÄ±ndan |
| `cost_usd` | DECIMAL(12,8) | Bu mesajÄ±n maliyeti |
| `created_at` | DATETIME | YazÄ±lma anÄ± |

| Karar | Neden |
|---|---|
| `DECIMAL(12,8)`, `FLOAT` deÄŸil | Para hiÃ§bir zaman kayan noktalÄ± sayÄ±yla tutulmaz; `FLOAT` toplamlarÄ± sessizce kaydÄ±rÄ±r. Sekiz ondalÄ±k, tek bir mesajÄ±n kesirli sentini taÅŸÄ±r |
| Toplamlar sohbet satÄ±rÄ±nda **da** var | Liste sayfasÄ± her satÄ±r iÃ§in mesaj tablosunu toplasaydÄ± N+1 sorgu doÄŸardÄ± |
| `thinking` ayrÄ± sÃ¼tun | YanÄ±t metniyle karÄ±ÅŸtÄ±rÄ±lmamalÄ±; ayrÄ±ca isteÄŸe baÄŸlÄ± gÃ¶sterilir |
| `role` `ENUM` | Ä°ki deÄŸer vardÄ±r ve Ã¼Ã§Ã¼ncÃ¼sÃ¼ bir hatadÄ±r; veritabanÄ± bunu kendisi engeller |
| KullanÄ±cÄ± mesajÄ±nda jeton `0` | Ãœcretlendirme, o mesajÄ± da iÃ§eren API Ã§aÄŸrÄ±sÄ±nÄ±n **yanÄ±t** satÄ±rÄ±nda toplanÄ±r; iki yerde saymak toplamÄ± bozardÄ± |
| `ON DELETE CASCADE` | Sohbet silinince mesajlar da gider; yetim satÄ±r **imkÃ¢nsÄ±z** olur |

---

### SSS

<details>
<summary><b>API anahtarÄ±nÄ± JavaScript'e koysam ne olur?</b></summary>

SayfayÄ± aÃ§an herkes onu gÃ¶rÃ¼r. `F12 â†’ Sources` yeterlidir; aÄŸ sekmesinde istek baÅŸlÄ±klarÄ±nda da durur.

SonuÃ§: anahtarÄ±nÄ±zla baÅŸkalarÄ± istek atar, faturayÄ± siz Ã¶dersiniz. AnahtarÄ± iptal edip yenisini Ã¼retmekten baÅŸka Ã§areniz kalmaz.

Kural basit: **API anahtarÄ± sunucudan Ã§Ä±kmaz.** TarayÄ±cÄ± yalnÄ±zca kendi sunucunuzla konuÅŸur.
</details>

<details>
<summary><b>Maliyeti nasÄ±l dÃ¼ÅŸÃ¼rÃ¼rÃ¼m?</b></summary>

DÃ¶rt kaldÄ±raÃ§ var, etkileri sÄ±rasÄ±yla:

1. **SaÄŸlayÄ±cÄ±.** En bÃ¼yÃ¼k fark burada: Gemini ve Groq'un Ã¼cretsiz katmanlarÄ± vardÄ±r. Bir yan projede fatura hiÃ§ baÅŸlamayabilir.
2. **Model.** AynÄ± ailede bile fark bÃ¼yÃ¼ktÃ¼r: `gemini-2.5-flash-lite` Ã§Ä±kÄ±ÅŸta `gemini-2.5-flash`'in altÄ±da biri, `claude-haiku-4-5` ise `claude-opus-5`'in beÅŸte biri fiyattadÄ±r. SÄ±nÄ±flandÄ±rma, Ã¶zetleme, biÃ§imlendirme gibi iÅŸlerde aradaki kalite farkÄ± Ã§oÄŸu zaman fark edilmez.
3. **GÃ¶nderdiÄŸiniz geÃ§miÅŸ.** GiriÅŸ jetonu her mesajda birikir. Uzun sohbetlerde eski mesajlarÄ± Ã¶zetleyip Ã¶zeti gÃ¶nderin.
4. **Efor seviyesi.** Claude'da `AI_EFFORT` dÃ¼ÅŸÃ¼rmek dÃ¼ÅŸÃ¼nme jetonlarÄ±nÄ± azaltÄ±r.

Hangisinin iÅŸe yaradÄ±ÄŸÄ±nÄ± gÃ¶rmek iÃ§in paneldeki maliyet sayacÄ±na bakÄ±n â€” Ã¶lÃ§meden optimize etmeyin.
</details>

<details>
<summary><b>YanÄ±t cÃ¼mlenin ortasÄ±nda kesiliyor</b></summary>

`stop_reason = "max_tokens"` demektir: yanÄ±t `AI_MAX_TOKENS` sÄ±nÄ±rÄ±na Ã§arptÄ±.

`.env` iÃ§indeki deÄŸeri yÃ¼kseltin. DÃ¼ÅŸÃ¼k tutmak tasarruf gibi gÃ¶rÃ¼nÃ¼r ama kesilen yanÄ±tÄ± baÅŸtan sormak zorunda kalÄ±rsÄ±nÄ±z â€” yani iki kez Ã¶dersiniz. VarsayÄ±lan 16.000 Ã§oÄŸu iÅŸ iÃ§in yeterlidir.

Ã‡ok uzun yanÄ±tlar iÃ§in akÄ±ÅŸ (streaming) gerekir; bu Ã¶rnekte akÄ±ÅŸsÄ±z istek kullanÄ±lmÄ±ÅŸtÄ±r.
</details>

<details>
<summary><b>Neden resmi SDK'yÄ± kullanmadÄ±nÄ±z?</b></summary>

Bu proje Messages API'sinin **nasÄ±l** Ã§alÄ±ÅŸtÄ±ÄŸÄ±nÄ± gÃ¶stermek iÃ§in yazÄ±ldÄ±: hangi baÅŸlÄ±klar gidiyor, yanÄ±t nasÄ±l ayrÄ±ÅŸÄ±yor, hangi hata kodu geÃ§ici.

SaÄŸlayÄ±cÄ± sÄ±nÄ±flarÄ± her adÄ±mÄ± yorumlarla aÃ§Ä±klar; ortak HTTP ve yeniden deneme katmanÄ± `HttpProvider` iÃ§inde bir kez yazÄ±lmÄ±ÅŸtÄ±r. AyrÄ±ca Composer baÄŸÄ±mlÄ±lÄ±ÄŸÄ± olmamasÄ±, paylaÅŸÄ±mlÄ± hosting'e atÄ±p Ã§alÄ±ÅŸtÄ±rabilmeniz demektir.

Ãœretimde SDK kullanmak isterseniz, artÄ±k onun ne yaptÄ±ÄŸÄ±nÄ± biliyor olacaksÄ±nÄ±z.
</details>

<details>
<summary><b>`429` alÄ±yorum, ne yapmalÄ±yÄ±m?</b></summary>

`429` hÄ±z sÄ±nÄ±rÄ±dÄ±r ve **geÃ§icidir**. Uygulama zaten Ã¼stel geri Ã§ekilmeyle en fazla 3 kez yeniden dener.

ÃœÃ§ deneme de yetmiyorsa istek hÄ±zÄ±nÄ±z hesabÄ±nÄ±zÄ±n sÄ±nÄ±rÄ±nÄ±n Ã¼stÃ¼nde demektir. SeÃ§enekler: istekleri kuyruÄŸa alÄ±p yavaÅŸÃ§a gÃ¶ndermek, daha kÃ¼Ã§Ã¼k bir model kullanmak veya hesap limitinizi yÃ¼kseltmek.

Kuyruk Ã¶rneÄŸi iÃ§in [Ä°ÅŸ KuyruÄŸu ve Worker Sistemi](https://cilginyazilim.com/kutuphane/php-queue-worker)'ne bakÄ±n.
</details>

<details>
<summary><b>Sohbet geÃ§miÅŸini sÄ±nÄ±rsÄ±z gÃ¶ndermek zorunda mÄ±yÄ±m?</b></summary>

HayÄ±r ve gÃ¶ndermemelisiniz. Model durum tutmadÄ±ÄŸÄ± iÃ§in her istekte tÃ¼m geÃ§miÅŸ yeniden Ã¼cretlendirilir; 50 mesajlÄ±k bir sohbette 51. soru Ã§ok pahalÄ±ya gelir.

YaygÄ±n kalÄ±p: son N mesajÄ± ham gÃ¶nderin, daha eskileri tek bir Ã¶zet mesajÄ±na indirin. Ã–zeti Ã¼retmek de bir API Ã§aÄŸrÄ±sÄ±dÄ±r ama bir kez Ã¶denir.
</details>

---

### CanlÄ± Ortama AlÄ±rken

- [ ] `.env` iÃ§inde `APP_DEBUG=false` (veya satÄ±rÄ± tÃ¼mÃ¼yle silin)
- [ ] API anahtarÄ± **yalnÄ±zca** `.env` iÃ§inde; depoda deÄŸil
- [ ] `.env` dosyasÄ±nÄ±n tarayÄ±cÄ±dan eriÅŸilemediÄŸini doÄŸrulayÄ±n (403 dÃ¶nmeli)
- [ ] `AI_MODEL` ve `AI_MAX_TOKENS` bÃ¼tÃ§enize gÃ¶re ayarlanmÄ±ÅŸ mÄ±?
- [ ] KullanÄ±cÄ± baÅŸÄ±na gÃ¼nlÃ¼k istek sÄ±nÄ±rÄ± dÃ¼ÅŸÃ¼nÃ¼n (bu Ã¶rnekte yoktur)
- [ ] Maliyet sayaÃ§larÄ±nÄ± dÃ¼zenli izleyin
- [ ] HTTPS zorunlu olsun
- [ ] VeritabanÄ± iÃ§in **root olmayan** bir kullanÄ±cÄ± aÃ§Ä±n
- [ ] Demo hesaplarÄ±nÄ±n parolalarÄ±nÄ± deÄŸiÅŸtirin veya hesaplarÄ± silin

---

### Sorun Giderme

| Belirti | Sebep | Ã‡Ã¶zÃ¼m |
|---|---|---|
| "API anahtarÄ± tanÄ±mlÄ± deÄŸil" | `.env` boÅŸ veya okunmuyor | SeÃ§ili saÄŸlayÄ±cÄ±nÄ±n anahtar satÄ±rÄ±nÄ± kontrol edin (`GEMINI_API_KEY`, `GROQ_API_KEY`, `ANTHROPIC_API_KEY`) |
| `401` geliyor | Anahtar geÃ§ersiz veya iptal edilmiÅŸ | Konsoldan yeni anahtar Ã¼retin |
| `429` sÃ¼rekli | HÄ±z sÄ±nÄ±rÄ± | Ä°stekleri yavaÅŸlatÄ±n veya kuyruÄŸa alÄ±n |
| YanÄ±t kesiliyor | `max_tokens` sÄ±nÄ±rÄ± | `AI_MAX_TOKENS` deÄŸerini yÃ¼kseltin |
| Maliyet `0,00` gÃ¶rÃ¼nÃ¼yor | Ãœcretsiz katmandasÄ±nÄ±z (doÄŸru) ya da `AI_MODEL` fiyat tablosunda yok | Gerekirse saÄŸlayÄ±cÄ±nÄ±n `PRICING` tablosuna modeli ekleyin |
| BaÄŸlantÄ± zaman aÅŸÄ±mÄ± | `curl` eklentisi yok veya giden baÄŸlantÄ± kapalÄ± | `php -m \| grep curl`; sunucu gÃ¼venlik duvarÄ±nÄ± kontrol edin |
| TÃ¼rkÃ§e karakterler bozuk | BaÄŸlantÄ± karakter kÃ¼mesi | `charset=utf8mb4` olduÄŸunu doÄŸrulayÄ±n |
| TÃ¼m adresler 404 | `mod_rewrite` kapalÄ± | AÃ§Ä±n veya `APP_PRETTY_URLS=false` yapÄ±n |

---

### Yol HaritasÄ±

- [ ] AkÄ±ÅŸ (streaming) desteÄŸi â€” yanÄ±t yazÄ±lÄ±rken gÃ¶stermek
- [ ] KullanÄ±cÄ± baÅŸÄ±na gÃ¼nlÃ¼k jeton/maliyet kotasÄ±
- [ ] Uzun sohbetlerde otomatik Ã¶zetleme
- [ ] Sistem istemi (system prompt) yÃ¶netimi
- [ ] AraÃ§ kullanÄ±mÄ± (tool use) Ã¶rneÄŸi
- [ ] Ã–n bellek (prompt caching) jetonlarÄ±nÄ±n ayrÄ± sayÄ±lmasÄ±

---

### KatkÄ±

Hata bildirimi ve Ã¶neriler iÃ§in [issue aÃ§abilirsiniz](https://github.com/CilginYazilim/ai-integration-system/issues).

### Lisans

[MIT](LICENSE) â€” ticari projelerinizde de Ã¶zgÃ¼rce kullanabilirsiniz.

---

**[Ã‡Ä±lgÄ±n YazÄ±lÄ±m](https://cilginyazilim.com)** Â· [Kaynak KÃ¼tÃ¼phanesi](https://cilginyazilim.com/kutuphane) Â· [TÃ¼m Ã–rnekler](https://github.com/CilginYazilim)

## SÄ±k Sorulan Sorular

### API anahtarÄ±nÄ± JavaScript'e koysam ne olur?

SayfayÄ± aÃ§an herkes onu gÃ¶rÃ¼r; F12 ile kaynak sekmesi yeterlidir. SonuÃ§: anahtarÄ±nÄ±zla baÅŸkalarÄ± istek atar, faturayÄ± siz Ã¶dersiniz. Kural basittir: API anahtarÄ± sunucudan Ã§Ä±kmaz, tarayÄ±cÄ± yalnÄ±zca kendi sunucunuzla konuÅŸur.

### Maliyeti nasÄ±l dÃ¼ÅŸÃ¼rÃ¼rÃ¼m?

ÃœÃ§ kaldÄ±raÃ§ var. Model seÃ§imi en bÃ¼yÃ¼ÄŸÃ¼dÃ¼r: claude-haiku-4-5 Ã§Ä±kÄ±ÅŸta claude-opus-5'in beÅŸte biri fiyattadÄ±r. Ä°kincisi gÃ¶nderdiÄŸiniz geÃ§miÅŸ: giriÅŸ jetonu her mesajda birikir, uzun sohbetlerde eski mesajlarÄ± Ã¶zetleyip Ã¶zeti gÃ¶nderin. ÃœÃ§Ã¼ncÃ¼sÃ¼ efor seviyesi. Hangisinin iÅŸe yaradÄ±ÄŸÄ±nÄ± gÃ¶rmek iÃ§in paneldeki maliyet sayacÄ±na bakÄ±n.

### GiriÅŸ jetonu neden her mesajda artÄ±yor?

Ã‡Ã¼nkÃ¼ model durum tutmaz. "Ã–nceki mesajÄ±mÄ± hatÄ±rla" diye bir ÅŸey yoktur; her istekte sohbetin tamamÄ± yeniden gÃ¶nderilir ve yeniden Ã¼cretlendirilir. Ã–rnek sohbette bunu somut gÃ¶rÃ¼rsÃ¼nÃ¼z: 412, sonra 890, sonra 1.503 jeton.

### YanÄ±t cÃ¼mlenin ortasÄ±nda kesiliyor, neden?

stop_reason deÄŸeri max_tokens demektir: yanÄ±t AI_MAX_TOKENS sÄ±nÄ±rÄ±na Ã§arpmÄ±ÅŸtÄ±r. .env iÃ§indeki deÄŸeri yÃ¼kseltin. DÃ¼ÅŸÃ¼k tutmak tasarruf gibi gÃ¶rÃ¼nÃ¼r ama kesilen yanÄ±tÄ± baÅŸtan sormak zorunda kalÄ±rsÄ±nÄ±z, yani iki kez Ã¶dersiniz.

### Neden resmi SDK kullanÄ±lmadÄ±?

Bu proje Messages API'sinin nasÄ±l Ã§alÄ±ÅŸtÄ±ÄŸÄ±nÄ± gÃ¶stermek iÃ§in yazÄ±ldÄ±: hangi baÅŸlÄ±klar gidiyor, yanÄ±t nasÄ±l ayrÄ±ÅŸÄ±yor, hangi hata kodu geÃ§ici. AyrÄ±ca Composer baÄŸÄ±mlÄ±lÄ±ÄŸÄ± olmamasÄ±, paylaÅŸÄ±mlÄ± hosting'e atÄ±p Ã§alÄ±ÅŸtÄ±rabilmeniz demektir.

### Demoda neden yanÄ±t Ã¼retemiyorum?

Demo sunucusunda API anahtarÄ± tanÄ±mlÄ± deÄŸildir; herkese aÃ§Ä±k bir demoda gerÃ§ek bir anahtar bulundurmak faturayÄ± ziyaretÃ§ilere aÃ§mak olurdu. Ekrandaki Ã¼Ã§ sohbet arayÃ¼zÃ¼ dolu gÃ¶stermek iÃ§in elle yazÄ±lmÄ±ÅŸ Ã¶rneklerdir; jeton ve maliyet sayÄ±larÄ± gerÃ§ek fiyat tablosuyla hesaplanmÄ±ÅŸtÄ±r.

---

Kaynak: [Yapay ZekÃ¢ Entegrasyonu (Claude API)](https://cilginyazilim.com/kutuphane/php-ai-integration)
