Skip to content

Robota "Al Şunu" Demek İçin 5 Satır Yeter 🤖

Published: March 26, 2026

Selamlar. Sizlerle bir hikaye paylaşmak istiyorum — robotlara nasıl konuşmayı öğrettik, ve bunu yaparken yazılımın en güzel tarafını keşfettik: basitlik.

🎧 First in first, background music.


Sorun Ne? 🤯

Bir robotu hareket ettirmek istiyorsun. Kolunu kaldır, küpü al, kutuya koy. Basit değil mi?

Hayır.

Gerçekte karşına çıkan şey: motor kontrol protokolleri, tensor boyutları, kamera kalibrasyonu, policy inference servisleri, Docker container'ları, ZMQ soketleri, TensorRT engine'leri...

Trendyol'da order detail sayfasında 15 farklı durum × 8 farklı component ile uğraşırken bitwise flags ile O(1)'e düşürmüştük hatırlarsanız. Aynı his. Karmaşıklığın altında yatan bir düzen var, onu bulmak lazım.

Kendime sordum, 🤔

Eğer ben bir robot olsaydım, hareket etmek için kaç satır kod görmek isterdim?

Cevabım: 5.

The 5-Line Promise ✨

from strands_robots import Robot
from strands import Agent

robot = Robot("so100")
agent = Agent(tools=[robot])
agent("Pick up the red cube")

Bu kadar. Gerçekten bu kadar.

Arka planda neler oluyor? Her şey. Kameralar açılıyor, policy modeli yükleniyor, action chunk'lar hesaplanıyor, servo motorlara komut gönderiliyor. Ama sen bunların hiçbirini bilmek zorunda değilsin.

Tıpkı bitwise config flags'te olduğu gibi — component'in neden render edildiğini bilmesine gerek yok. shouldRender der, cevabını alır, işini yapar.

graph LR
    A["'Pick up the red cube'"] --> B[Strands Agent]
    B --> C[Robot Tool]
    C --> D[Policy Provider<br/>GR00T / ACT / Pi0]
    C --> E[LeRobot<br/>Hardware Abstraction]
    D --> F[Action Chunk<br/>16 timesteps]
    F --> E
    E --> G["🤖 Robot Hardware"]

    classDef input fill:#2ea44f,stroke:#1b7735,color:#fff
    classDef agent fill:#0969da,stroke:#044289,color:#fff
    classDef policy fill:#8250df,stroke:#5a32a3,color:#fff
    classDef hardware fill:#bf8700,stroke:#875e00,color:#fff

    class A input
    class B,C agent
    class D,F policy
    class E,G hardware

Neden "Strands"? 🧬

Strands Agents, Amazon'un açık kaynak AI agent framework'ü. 5000+ yıldız, model-agnostic, birkaç satırda agent yazarsın. Ama benim için güzel olan şey — tool konsepti.

Strands'te her şey bir tool. Shell komutu bir tool. GitHub API bir tool. Ve — bir robot da bir tool.

from strands import Agent, tool

@tool
def hello(name: str) -> str:
    """Say hello."""
    return f"Hello, {name}!"

agent = Agent(tools=[hello])
agent("Say hello to the world")

Bu kadar basit bir API'nin üstüne robotu da bir tool olarak koyduğunda, agent doğal dilde sana cevap verirken arka planda motor kontrol yapıyor. Büyülü.

Strands'in Gücü

  • 🎯 Model-Agnostic: Bedrock, Anthropic, OpenAI, Ollama, Gemini — hepsi çalışır
  • 🔧 Tool-First: Her capability bir tool, kolayca genişler
  • 🪶 Lightweight: SDK 5000 satır. Framework değil, SDK.
  • 🌐 Open Source: Apache 2.0, herkes katkı verebilir

19 Policy Provider, 38 Robot 🏭

Bitwise flags'te GRAPH değişkeni tüm durumları tutuyordu ya — burada da bir registry var. JSON-driven, deklaratif.

mindmap
  root((strands-robots))
    Policy Providers
      ACT
      Diffusion Policy
      Pi0
      SmolVLA
      GR00T N1
      OpenVLA
      LeRobot Local
      LeRobot Async
      DreamGen
      ...19 total
    Robots
      SO-100 / SO-101
      Fourier GR-1
      Unitree G1 / H1
      Bimanual Panda
      ALOHA
      Koch v1.1
      Moss v1
      ...38 total
    Devices
      Jetson Orin
      EC2 L40S
      MacBook MPS
      Any CUDA box

Yeni bir robot eklemek? JSON'a bir satır yaz. Yeni bir policy? BasePolicy'den inherit et, 3 method implement et. Bitti.

Bu yaklaşımı bitwise config flags'ten öğrendim aslında. Config-map üzerinden business logic'i yönetmek. Orada GRAPH değişkeniydi, burada registry JSON. Aynı felsefe:

Kodu değiştirme, config'i değiştir.

Yaklaşım #1: Naive Yol 😵

Klasik robotik kodlama:

import torch
import cv2
import serial
from lerobot.common.policies.act.modeling_act import ACTPolicy

# Camera setup - 47 lines
cap = cv2.VideoCapture("/dev/video0")
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
# ... calibration, FPS, color space...

# Model loading - 23 lines  
model = ACTPolicy.from_pretrained("checkpoint")
model.to("cuda")
model.eval()

# Servo setup - 31 lines
bus = serial.Serial("/dev/ttyACM0", 1000000)
# ... protocol, calibration, limits...

# Inference loop - 89 lines
while True:
    frame = cap.read()
    obs = preprocess(frame)  # tensor shapes, normalization...
    with torch.no_grad():
        actions = model(obs)
    for action in actions:
        send_to_servo(bus, action)  # protocol encoding...

~190 satır. Her robot için yeniden yaz. Her policy için yeniden yaz. N robot × M policy = 🤯

Tanıdık geldi mi? Order detail sayfasındaki 15 × 8 = 120 kombinasyon gibi.

Yaklaşım #2: Biraz Daha İyi 🤔

Soyutlama katmanları ekle. RobotBase, PolicyBase, factory pattern...

robot = RobotFactory.create("so100", port="/dev/ttyACM0")
policy = PolicyFactory.create("act", checkpoint="path/to/model")

robot.connect()
while True:
    obs = robot.get_observation()
    action = policy.predict(obs)
    robot.execute(action)

~30 satır. Daha iyi. Ama hala sen loop yazıyorsun. Hala sen policy seçiyorsun. Hala sen observation format'ını bilmek zorundasın.

Yaklaşım #3: Esoterik Yol 🪄

Bitwise'da "eğer ben bir component olsaydım, neden burada olduğumu bilmek ister miydim?" demiştim.

Aynı soruyu robota soruyorum:

Eğer ben bir robotsam, policy'nin ne olduğunu bilmek zorunda mıyım?

Hayır. Robot sadece "al şunu" der. Gerisini sistem çözer.

robot = Robot("so100")
agent = Agent(tools=[robot])
agent("Pick up the red cube")
flowchart TB
    subgraph "What You Write"
        A["agent('Pick up the red cube')"]
    end

    subgraph "What Happens (Invisible)"
        B[Agent parses intent]
        C[Robot tool activated]
        D[Camera capture]
        E[Policy inference]
        F[Action chunking]
        G[Servo execution]
    end

    A --> B --> C --> D --> E --> F --> G

    style A fill:#2ea44f,stroke:#1b7735,color:#fff,stroke-width:4px
    style B fill:#333,stroke:#555,color:#aaa
    style C fill:#333,stroke:#555,color:#aaa
    style D fill:#333,stroke:#555,color:#aaa
    style E fill:#333,stroke:#555,color:#aaa
    style F fill:#333,stroke:#555,color:#aaa
    style G fill:#333,stroke:#555,color:#aaa

Üstteki yeşil kutu — senin yazdığın. Alttaki gri kutular — senin bilmene gerek olmayan. Tıpkı shouldRender gibi. O(1) karar.

Import Hızı: 66 Saniyeden 0.07'ye ⚡

Bir anekdot. İlk versiyonda import strands_robots 66 saniye sürüyordu. Neden? Çünkü her policy provider'ı eager loading ile yüklüyorduk. PyTorch, TensorRT, her şey.

# ❌ Eski — 66 saniye
import strands_robots  # Loads EVERYTHING

# ✅ Yeni — 0.07 saniye  
import strands_robots  # Loads nothing
robot = Robot("so100")  # Loads only what's needed

__getattr__ ile lazy loading. Component'in neden render edildiğini bilmesine gerek yok, import'un neden yapıldığını bilmesine de gerek yok. İhtiyaç olduğunda yüklenir.

Lesson Learned

Heavy deps load on first USE, not first IMPORT. Bu fark, 66 saniye ile 0.07 saniye arasındaki fark.

GTC 2026: Demo Anı 🎬

NVIDIA GTC 2026'da sahnedeydik. SO-100 robot kolu, iki kamera, bir Jetson Orin, ve Strands Agents.

Sahne:
  - Robot masada duruyor
  - Önünde kırmızı ve mavi küpler
  - Bir kutu

Demo:
  "Pick up the red cube and put it in the box"

  Robot → küpü alıyor → kutuya koyuyor.

  5 satır kod. Canlı sahne. 🎤⬇️

Bu an, bitwise flags yazısındaki "Bon appetit!" anı gibi. Karmaşık bir problemi zarif bir şekilde çözdüğünde hissettiğin o tatmin.

Strands Ekosistemi: Büyük Resim 🌍

graph TB
    subgraph "Strands Agents Ecosystem"
        SDK[strands-agents/sdk-python<br/>⭐ 5,374]
        Tools[strands-agents/tools<br/>⭐ 987]
        Robots[strands-robots<br/>🤖 Robot Control]
        MLX[strands-mlx<br/>🍎 Apple Silicon]
        DD[DevDuck<br/>🦆 Terminal Agent]
    end

    subgraph "You Build"
        App[Your Agent App]
    end

    App --> SDK
    SDK --> Tools
    SDK --> Robots
    SDK --> MLX
    SDK --> DD

    style SDK fill:#f9f,stroke:#333,stroke-width:4px
    style Robots fill:#bbf,stroke:#333,stroke-width:2px
  • SDK: Çekirdek. Agent + Tool + Model abstraction.
  • Tools: Shell, file, GitHub, calculator... her şey.
  • Robots: Doğal dille robot kontrolü. Bu yazının konusu.
  • MLX: Apple Silicon'da local inference.
  • DevDuck: Benim terminal agent'ım. Self-healing, hot-reload, ambient mode.

Hepsi birbirine bağlanıyor. Hepsi tool konseptinin üstüne inşa edilmiş. Hepsi birkaç satır.

Peki Ya Gerçek Hayat? 🔴

PR #56. 5 round review. 50+ thread. @awsarron ile satır satır.

Öğrendiğim şeyler silikon hafızama kazındı:

Robotik Kodda Asla

# ❌ YANLIŞ — Robot duvara çarpar
logger.warning("No model loaded")
return []

# ✅ DOĞRU — Robot durur, hata verir
raise ValueError("No model loaded — cannot generate actions")

Error handling'de warn-and-continue yapma. Sıfır action alan robot, duvara giden robottur.

Tüm Platformlarda Test Et

MacBook'ta çalışıyor ≠ Jetson'da çalışıyor ≠ EC2'de çalışıyor. CUDA-only crash'ler MPS'te görünmez.

Sokak Sanatçısı ve Robot 🎷

"Yazılımda Sokak Sanatçısı Olmak" yazısında demiştim ki:

Sadece sevdiğin işi yapmaya devam et. 🤘

Robot kontrolü de öyle. Büyük şirketlerde, büyük bütçelerle yapılan bir şeyi alıp, 5 satıra indirip, açık kaynak yapıp, herkese sunmak — bu sokak sanatçılığı.

Pieter Levels nomad yaşıyor, Sindre Sorhus CLI tool'lar yazıyor, biz de robotlara konuşmayı öğretiyoruz. Aynı ruh: sevdiğin işi yap, paylaş, katma değer üret.

Sırada Ne Var? 🔮

timeline
    title Strands Robots Roadmap
    Phase 1 : More Policy Providers
            : 19 total — ACT, Diffusion, Pi0, SmolVLA...
    Phase 2 : Simulation Backends  
            : MuJoCo, Isaac Sim, Newton
    Phase 3 : Training & Data Pipelines
            : DreamGen, Cosmos, RL
    Phase 4 : Robot Mesh
            : Zenoh P2P auto-discovery between robots
    Phase 5 : 3D World Generation
            : Marble Pipeline — AI-generated environments

Phase 4 özellikle heyecan verici. DevDuck'taki Zenoh swarm networking'i robotlara da getiriyoruz. Robotlar birbirini keşfedecek, görev paylaşacak, birlikte çalışacak. Bir nevi robot swarm'ı.

Başla 🚀

pip install strands-agents strands-robots
from strands_robots import Robot
from strands import Agent

robot = Robot("so100")
agent = Agent(tools=[robot])
agent("Pick up the red cube")

Hepsi bu. 5 satır. Bir robot. Bir agent. Doğal dil.


Bu yaklaşım bize ne kazandırdı?

  • ✅ Esnek robot ekleme/çıkarma — config-driven registry
  • ✅ Tekrar kullanılabilir policy'ler — business logic kırılmaz
  • ✅ Okunabilir kod — 5 satır, başka açıklama gerekmez
  • ✅ O(1) karar karmaşıklığı — agent söyle, robot yapsın
  • ✅ Kolay test — mock policy ile hardware olmadan test et
  • ✅ Beginner-friendly — ilk günden çalışır

Bitwise config flags'te O(n)'i O(1)'e düşürmüştük. Burada da 190 satırı 5'e düşürdük. Aynı felsefe, farklı domain.

Afiyet olsun! 🍽️

Çağatay.