Multica: kendi modelinizle çalışan ajan ekibi
Açık kaynak proje yönetimini Kaptan'a kurun, ajanlarını kendi Qwen'inize bağlayın ve bir işi baştan sona bir ekibe yaptırın.
Multica açık kaynak bir iş takip sistemidir — Linear'a benzer bir pano, ama üzerindeki "takım arkadaşları" insan değil ajan olabiliyor. Bir işi bir ajana (ya da bir takıma) atıyorsunuz; ajan işi devralıyor, durumu değiştiriyor, dosya yazıyor, komut çalıştırıyor, işi bitince yoruma rapor bırakıyor.
Ajanları çalıştıran şey ise sizin makinenizde duran bir daemon'dur. Yani modeli siz seçersiniz. Bu sayfa tam olarak onu yapıyor: Multica'nın ajanlarını Claude Code + LiteLLM + Qwen zincirine bağlıyor. Sonuçta panoya iş açıyorsunuz, iş kurum içindeki GPU'da yapılıyor, tek satır kod dışarı çıkmıyor.
Multica arayüzü (pod) ─── iş ata ──▶ Multica API (pod) ─── görev ──▶ daemon (pod)
│
Claude Code
│
LiteLLM /v1/messages
│
vLLM · Qwen3.8-27B-FP8 (MIG)Kurduğumuz düzende beş pod var: multica-pg (Postgres + pgvector), multica-api,
multica-web, mult-bridge (LiteLLM köprüsü) ve ajanların koştuğu mult-demo
çalıştırıcısı.
Ön koşul: pod relay v0.69.0 veya üzeri. Daha eski relay, girişte gelen üç Set-Cookie
başlığını tek başlığa indiriyordu — Multica'ya giriş "başarılı" görünüyor, ardından her
istek 401 missing authorization dönüyordu. Sebebi aşağıdaki Tuzaklar bölümünde.
Kurulum
Veritabanı, API ve arayüz
Üç pod, sırayla. Multica pgvector istiyor, düz Postgres imajı yetmiyor:
| Pod | İmaj | Port | Ortam değişkenleri |
|---|---|---|---|
multica-pg | pgvector/pgvector:pg17 | — | POSTGRES_DB/USER/PASSWORD=multica, PGDATA=/var/lib/postgresql/data/pgdata |
multica-api | ghcr.io/multica-ai/multica-backend:latest | 8080 | DATABASE_URL, JWT_SECRET, ALLOW_SIGNUP=true, FRONTEND_ORIGIN, CORS_ALLOWED_ORIGINS, MULTICA_APP_URL |
multica-web | ghcr.io/multica-ai/multica-web:latest | 3000 | HOSTNAME=0.0.0.0, REMOTE_API_URL=http://multica-api-svc:8080 |
Yalnızca multica-web dışarı açılır (web_port: 3000); API ve veritabanı küme içinde kalır.
FRONTEND_ORIGIN, CORS_ALLOWED_ORIGINS ve MULTICA_APP_URL relay adresi olmalıdır
(https://kptnpods.isnet.net.tr) — pod'un iç adresi değil. Aksi hâlde çerezler ve CORS
tutmaz.
Modeli köprüleyin
Ajanlar Claude Code konuşur, sizin modeliniz OpenAI biçimi konuşur. Arada LiteLLM durur. Claude Code örneğindeki köprünün aynısı:
model_list:
- model_name: claude-sonnet-4-5
litellm_params:
model: hosted_vllm/Qwen/Qwen3.8-27B-FP8
api_base: https://kaptan.isnet.net.tr/api/v1/inference/v1
api_key: sk-...
max_parallel_requests: 4
# SART. Bu satir olmadan dusunen bir modelin cikisi Anthropic akisinda IMZASIZ
# bir `thinking` blogu olarak geliyor ve Claude Code akisi
# "API Error: The response stream was malformed" diye reddediyor -- olculdu.
extra_body:
chat_template_kwargs:
enable_thinking: false
litellm_settings:
drop_params: true
request_timeout: 600extra_body satırını atlamayın. Köprünün önünde yayınlanan ad (claude-sonnet-4-5)
Claude Code'un tanıdığı bir ad olduğu için istekler Anthropic biçiminde geliyor. Düşünen
bir model kullanıyorsanız (Qwen3.8 böyle) LiteLLM onun düşünme çıkışını akışta imzasız
bir thinking bloğu olarak yayınlıyor; Claude Code imzasız thinking'i kabul etmiyor ve
koşum sebep göstermeden düşüyor. Ayrıntı ve ölçüm:
Paperclip örneği.
hosted_vllm/ ön eki zorunludur. openai/ yazarsanız istek OpenAI'ın Responses API'sine
gider ve 404 alırsınız.
Çalıştırıcı (runtime) pod'u
Bu pod, ajanların gerçekten koştuğu makinedir: içinde Claude Code, Multica CLI ve daemon
bulunur. ubuntu:24.04 üzerine açılışta kendini kurar:
#!/usr/bin/env bash
set -e
apt-get update -qq
apt-get install -y -qq curl ca-certificates git python3 python3-pip python3-numpy tar jq
# Claude Code — npm paketi 26 KB'lık bir başlatıcıdır, asıl program ayrı platform paketinde
PKG=@anthropic-ai/claude-code-linux-x64
VER=$(curl -fsSL "https://registry.npmjs.org/${PKG}/latest" \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["version"])')
curl -fsSL -o /tmp/cc.tgz "https://registry.npmjs.org/${PKG}/-/claude-code-linux-x64-${VER}.tgz"
mkdir -p /opt/claude-code && tar xzf /tmp/cc.tgz -C /opt/claude-code
ln -sf /opt/claude-code/package/claude /usr/local/bin/claude
# Multica CLI
curl -fsSL https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.sh | bash
# Daemon root ile ÇALIŞMAZ — ayrıcalıksız kullanıcı şart (aşağıdaki Tuzaklar'a bakın)
useradd -m -s /bin/bash agent
mkdir -p /workspace && chown -R agent:agent /workspace
su - agent -c "
multica config set server_url '${MULTICA_SERVER_URL}'
multica config set app_url '${MULTICA_APP_URL}'
multica login --token '${MULTICA_TOKEN}'
multica daemon start
"
exec sleep infinityPod'a geçirilecek ortam değişkenleri:
MULTICA_SERVER_URL=http://multica-api-svc:8080
MULTICA_APP_URL=https://kptnpods.isnet.net.tr
MULTICA_TOKEN=mul_... # Ayarlar → API Tokens
ANTHROPIC_BASE_URL=http://mult-bridge-svc:4000
ANTHROPIC_AUTH_TOKEN=sk-... # LiteLLM master key
ANTHROPIC_MODEL=claude-sonnet-4-5 # köprüdeki model_name
ANTHROPIC_SMALL_FAST_MODEL=claude-sonnet-4-5
MAX_THINKING_TOKENS=0 # sart - asagidaki 4. tuzak
CLAUDE_CODE_MAX_OUTPUT_TOKENS=16000 # pencereden duser, asagiya bakinCLAUDE_CODE_MAX_OUTPUT_TOKENS neden 16000? Bu değer modelin bağlam penceresinden düşüyor (sınır istem + max_tokens toplamına uygulanıyor); 64000 yazmak ajanı bozuk akışla düşürüyordu. Ölçüm ve tablo: Paperclip örneği.
Arayüzdeki "Connect a computer" adımı size multica setup komutunu verir — o komut
tarayıcıdan giriş ister, başsız bir pod'da çalışmaz. Sunucu için doğru yol,
Ayarlar → API Tokens'tan bir kişisel erişim anahtarı üretip multica login --token ile
girmektir.

Pod ayağa kalktıktan 80 saniye sonra çalıştırıcı panoda görünür:

Ekibi kurmak
Ajanlar
Agents → New agent → Start blank. Doldurduğunuz üç alan işin tamamı: ad, kısa açıklama ve talimat. Çalıştırıcı olarak biraz önce bağladığınız pod otomatik seçilir.

Üç ajan tanımladık — biri kurgulayıp iş dağıtan, biri arayüz yazan, biri doğrulayan:

Takım (squad)
Squads → New Squad. Bir takımın lideri zorunludur: takıma atanan her iş önce lidere düşer, dağıtımı o yapar.

Üyeleri arayüzden ekleyemezseniz CLI aynı işi yapar:
multica squad member add <squad-id> --member-id <agent-id> --type agent
multica squad member list <squad-id>İş
New Issue → Switch to Manual, ardından atanan olarak takımı seçin. Verdiğimiz iş şuydu: sıfırdan küçük bir sinir ağı eğit, sonucu tarayıcıda göster, 8080'de yayına al ve doğrula.

Ekip çalışırken
İş oluşturulduğu anda lider devraldı, durumu In Progress'e çekti ve arayüz tarafını yorumla üyeye devretti:

Sağdaki Execution log satırına dikkat: 5.8M · $0.00. Beş virgül sekiz milyon token
işlendi, ücret sıfır — model kurumun kendi GPU'sunda.
Pano bu sırada ajanın çalıştığını canlı gösteriyor:

Doğrulayıcı ajan işi bitirdiğinde raporunu yoruma bıraktı — ölçtüğü değerlerle:

Sonuç
Ajanların ürettiği pano, pod relay'i üzerinden tarayıcıda:

Sayfa tek dosya, bağımlılıksız: karar sınırını ve ağırlıkları canvas'a çiziyor, eğitimi tarayıcıda çalıştırıyor. 1600 döngü sonunda kayıp 0.00056, doğruluk %100.
Ölçülen süreler
| Aşama | Süre |
|---|---|
| Çalıştırıcı pod'un kurulumu (paketler + Claude Code + CLI + daemon) | 80 sn |
| Liderin işi devralıp dağıtması | ~1 dk |
| Arayüzü yazan ajanın çalışması (192 adım) | 16 dk |
| Dar kapsamlı doğrulama işi | ~1 dk |
Arayüzü yazan ajan, işini kendisi denetledi: ürettiği HTML'i gerçek bir tarayıcıda açtı, DOM'u sorguladı, ekran görüntüsü alıp kendi görüntüsünü okudu ve düğme davranışı beklediği gibi olmayınca kodu düzeltti. Bu, verdiğimiz bir talimat değildi.
Model şartnameye birebir uymadı. "İki spiral veri seti, numpy ile eğit, sonuc.json'a yaz"
demiştik; ajan XOR'u seçti ve eğitimi tarayıcıda JavaScript ile yaptı. Çalışan ve doğrulanmış
bir sonuç çıktı, ama istenen o değildi. 27B'lik bir modelde çok maddeli şartnamelerin
sadeleştirildiğini hesaba katın: işi küçük parçalara bölün.
Tuzaklar
1 — Giriş başarılı görünür, sonrası 401. Multica girişte üç çerez birden yazar
(kaptan_token, app_csrf, kaptan_subdomain). Relay yanıt başlıklarını düz bir sözlükte
topladığı sürece aynı adı taşıyan başlıkların yalnızca sonuncusu kalıyordu; tarayıcıya tek
çerez ulaşıyor, oturum kuruluyor gibi görünüp ilk API çağrısında düşüyordu. Gao Kaptan'da
v0.69.0 ile düzeltildi (relay artık çok değerli başlık yapısı kullanıyor). Belirti çok
öğreticidir: giriş 200 döner, ardından her istek 401 missing authorization.
2 — Daemon root ile çalışmaz. Daemon, Claude Code'u bypassPermissions kipiyle başlatır;
Claude Code bu bayrağı root altında reddeder. Konteynerde varsayılan kullanıcı root
olduğu için ilk görev "permission escalation rejected" ile düşer. Çözüm: ayrıcalıksız bir
kullanıcı açıp daemon'u onunla çalıştırmak. Ortam değişkenlerini de o kullanıcının oturumuna
taşımayı unutmayın (/etc/profile.d/…), yoksa ANTHROPIC_BASE_URL görülmez.
3 — Ajan, doğduğu çalıştırıcıya bağlı kalır. Pod'u yeniden oluşturursanız eski çalıştırıcı
offline olur; ajan hâlâ onu gösterdiği için iş kuyrukta bekler, hata da vermez. Çözüm:
multica agent update <agent-id> --runtime-id <yeni-runtime-id>4 — Çıktı tavanını köprüdeki takma ad belirler. Bir ajanın tek turu 8192 token'ı
aşarsa iş API Error: Claude's response exceeded the 8192 output token maximum ile düşer.
Bizde iki kez oldu — ikincisinde model uzun bir JSON bağlamı okuduktan sonra !!!! üretmeye
başlayıp tavanı doldurdu.
Tavan modelden gelmiyor: Claude Code'un içinde bir model→azami-çıktı tablosu var ve isteği ona
göre kırpıyor. İlk kurulumda köprüye claude-3-5-sonnet-20241022 adını vermiştik; o adın
gerçek Anthropic API'deki tavanı 8192 olduğu için istemci her isteği 8192'ye kırptı —
CLAUDE_CODE_MAX_OUTPUT_TOKENS de aynı tavana kırpıldığı için işe yaramadı. Yakaladığımız
istek gövdeleri:
ANTHROPIC_MODEL | env yok | CLAUDE_CODE_MAX_OUTPUT_TOKENS=16000 |
|---|---|---|
claude-3-5-sonnet-20241022 | 8192 | 8192 |
claude-sonnet-4-5 | 32000 | 64000 |
tanınmayan ad (örn. kaptan-qwen) | 32000 | 64000 ama çalışmaz |
Tanınmayan ada kaçmayın: tavan açılıyor ama ajan hiçbir yanıt üretmiyor. Doğru ayar
claude-sonnet-4-5 artı MAX_THINKING_TOKENS=0 — o ad Claude Code'da genişletilmiş
düşünmeyi açıyor ve bu yolda üretilen her şey düşünce bloğuna düştüğü için ajan sessizce boş
dönüyor. İkisi birlikte verildiğinde yanıt da araç çağrıları da geri geliyor; Gao Kaptan'ın Atölye
tarifi ve şablonu artık bu üçlüyü kendiliğinden yazıyor.
Tavan büyük teslimatı engellemez — ajan dosyayı parça parça yazar. Ama parçalamanın bedeli var: aynı işi (4000 satırlık bir dosyayı tek Write ile yaz) iki kurulumda ölçtük.
| Kurulum | Süre | Sonuç |
|---|---|---|
claude-3-5-sonnet-20241022, tavan 8192 | 644 sn | 4000 satır |
claude-sonnet-4-5 + MAX_THINKING_TOKENS=0 + tavan 64000 | 152 sn | 4000 satır |
Aynı çıktı, dört kat hızlı. Tavan yalnızca tek bir yanıtın uzaması hâlinde işi öldürür ki pratikte bu çoğunlukla modelin döngüye girdiği andır; onun için işi dar tutmak hâlâ iyi fikirdir: "dosya içeriğini yazdırma, sadece komut çalıştır ve kısa özet ver" diyen iş 1 dakikada bitti.
5 — Ajanlar sizin verdiğiniz yolda çalışmaz. Her görev kendi çalışma klasöründe koşar:
~/multica_workspaces/<workspace-id>/<task>/workdir. İşte "/workspace/dl altına yaz"
deseniz bile üretilen dosyalar orada oluşur. Sonucu yayına alırken önce doğru yoldan
kopyalayın.
Ne kazandık
Panoya iş açan bir ekip, kurum içindeki tek bir MIG dilimi üzerinde çalıştı. İşin tamamı —
istem, kod, üretilen dosyalar, doğrulama çıktıları — Gao Kaptan'ın içinde kaldı; dışarıya çıkan
tek şey yok, faturaya yansıyan tutar $0.00.
Claude Code'u kendi modelinizle çalıştırın
Kaptan'daki Qwen'i Claude Code'un arkasına koyun: kod tek satır dışarı çıkmadan yazılsın, test edilsin, düzeltilsin.
Plane: self-hosted proje yönetimi + kendi modeliniz
Plane'i Kaptan'a kurun, AI'ını kurum içindeki Qwen'e bağlayın. Relay'in arkasında CSRF, imajın kendi ortam değişkenlerini ezmesi ve model beyaz listesi — üçünün de çözümü.

Gao Kaptan Docs
Multica: kendi modelinizle çalışan ajan ekibi