TR ▾
API anahtarı al

GLM API Python: Sohbet, Akış ve Araç Örnekleri

glm api python işleri için standart openai paketi yeterlidir: https://api.glmapi.cc/v1 adresini hedef alın, model ID olarak uncensored'ı kullanın ve normal sohbet çağrıları çalışır. Bu sayfa, ilk istekten eşzamanlı toplu işlere ve hız limiti işleme kadar her deseni kod örnekleriyle anlatır.

Temel noktalar

  • openai paketini yükleyin, base_url'yi https://api.glmapi.cc/v1 olarak ayarlayın ve uncensored modelini kullanın.
  • Akış, JSON modu ve fonksiyon çağırma, OpenAI sohbet API'si ile aynı parametreleri kullanır.
  • Tam anahtar 8 eşzamanlı istek ve dakikada 300 istek sağlar, bu nedenle eşzamanlı işçilerinizi 8'e kadar sınırlandırın.
  • 429 hatasını hata kodunu ve Retry-After başlığını okuyarak yönetin.
Python API çağrılarını temsil eden dizüstü bilgisayar terminalinden bulut sunucusuna akan ışık şeridi veri blokları

Kurulum ve ilk istek

Sanal ortam oluşturun ve SDK'yı yükleyin. openai paketinin sürüm 1 veya sonrası varsayılır.

python -m venv .venv
source .venv/bin/activate
pip install --upgrade openai

API anahtarı sayfasından bir anahtar alın; yeni kullanıcılar tek tıkla 7 gün geçerli ve kart gerektirmeyen $0.50 deneme kredisi alabilir. Anahtarı bir ortam değişkeninde tutun, ardından ilk çağrıyı yapın:

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.glmapi.cc/v1",
    api_key=os.environ["GLM_API_KEY"],
)

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": "You are a concise writing assistant."},
        {"role": "user", "content": "Suggest five titles for a space-western novel."},
    ],
    temperature=0.8,
)

print(resp.choices[0].message.content)
print(resp.usage)

Bu tüm entegrasyondur. Hizmet, tek bir açık ağırlıklı model için bağımsız, OpenAI uyumlu bir uç noktadır, bu nedenle GLM'nin arkasındaki tedarikçinin veya başkasının resmi API'si değildir. Sadece POST /v1/chat/completions ve GET /v1/models mevcuttur. hızlı başlangıç desteklenen istek alanlarını listeler.

İki küçük alışkanlık başlangıçta yardımcı olur. İlk olarak, bir smoke testinde client.models.list()'i bir kez çağırın: bu GET /v1/models'e erişir, böylece bir tamamlama için tek bir token harcamadan önce anahtarın, temel URL'nin ve ağ yolunun çalıştığını kanıtlar. İkinci olarak, geliştirme sırasında resp.usage'i yazdırın. İstem ve tamamlama token sayıları, bir sistem isteminizin düşündüğünüzden daha büyük olup olmadığını erken gösterir ve 1M başına $0.15 giriş ve 1M başına $0.50 çıkış fiyatıyla bir çağrıyı zihninizde fiyatlandırabilirsiniz.

Çoklu sohbet ve örnekleme ayarları

API durum bilgisi taşımaz, bu nedenle konuşma listesini kendiniz tutar ve her seferinde gönderirsiniz. Küçük bir sınıf yeterlidir:

class Chat:
    def __init__(self, client, system, max_turns=12):
        self.client = client
        self.system = system
        self.max_turns = max_turns
        self.history = []

    def say(self, text):
        self.history.append({"role": "user", "content": text})
        window = self.history[-self.max_turns * 2:]
        resp = self.client.chat.completions.create(
            model="uncensored",
            messages=[{"role": "system", "content": self.system}] + window,
            temperature=0.9,
            top_p=0.95,
            frequency_penalty=0.3,
        )
        reply = resp.choices[0].message.content
        self.history.append({"role": "assistant", "content": reply})
        return reply

self.history[-self.max_turns * 2:] dilimi son on iki kullanıcı ve asistan çiftini korur. Gerçek bir uygulama ayrıca birkaç erken mesajı sabitleyebilir, örneğin bir karakter sayfası veya temel gerçekler gibi ve ortayı özetleyebilir. Son 12 adıma kırpma, konuşma büyüdükçe giriş maliyetini sabit tutar. Bağlam penceresi istem ve tamamlama için birlikte 100.000 token içerir, bu nedenle bu bir zorunluluktan çok bir maliyet seçimidir. temperature, top_p, stop, seed parametreleri ve cezalar aktarılır. Bir istemi test ederken tekrarlanabilir çalıştırmalar istediğinizde seed'i ayarlayın ve uzunluğu sınırlamak istemediğiniz sürece max_tokens'i dışarıda bırakın.

Akış yanıtları

Akış, sunucu tarafından gönderilen olayları kullanır ve tokenları oluşturulurken size verir, bu da herhangi bir etkileşimli araç için önemlidir. stream=True parametresini iletin ve döngü kurun:

stream = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Describe a harbour at dawn in 120 words."}],
    stream=True,
)

parts = []
for chunk in stream:
    if not chunk.choices:
        continue
    delta = chunk.choices[0].delta.content
    if delta:
        parts.append(delta)
        print(delta, end="", flush=True)

text = "".join(parts)

chunk.choices üzerindeki kontrol önemlidir çünkü son parça kullanım bilgisi taşır ve boş bir choices listesi içerebilir. Operasyonel bir nokta: akışlı bir istek, akış bitene kadar eşzamanlılık yuvasını tutar. Döngüyü, kodunuz yolda bir hata verirse (örneğin bir istemci bağlantısı koptuğunda) akışı kapatan bir finally bloğu ile bir try bloğu içine alın. Akışı her zaman sonlandırın veya kapatın, aksi takdirde akışları terk eden bir döngü, hiçbir faydalı iş yapmadan eşzamanlılık sınırına çarpar.

JSON modu

Çıktı başka kodu beslediğinde bir JSON nesnesi isteyin. Beklenen şekli modele bildirmek için JSON'u istemde de belirtin:

import json

resp = client.chat.completions.create(
    model="uncensored",
    response_format={"type": "json_object"},
    messages=[
        {"role": "system", "content": "Reply with a JSON object only."},
        {"role": "user", "content": "Give a character with keys name, age, motto."},
    ],
)

data = json.loads(resp.choices[0].message.content)
print(data["name"])

Hala üretim kodunda json.loads'i bir try bloğuna sarın. JSON modu geçerli bir çıkış olasılığını artırır, ancak bir durdurma dizisi veya kendi sınırınız tarafından kesilen bir istek hala kesik bir nesne bırakabilir. Aynı girdiyle bir kez yeniden denemek ucuz bir çözümdür ve başarısız istekler ücretlendirilmediğinden, yeniden denemenin maliyeti yalnızca başarılı olan çağrıdır.

Araç çağırma

Araç çağırma OpenAI formatını izler: tools içinde fonksiyonları tanımlarsınız, model tool_calls döndürür, onları çalıştırırsınız ve sonuçları tool rolüyle geri gönderirsiniz. Tam bir dönüş:

import json

tools = [{
    "type": "function",
    "function": {
        "name": "roll_dice",
        "description": "Roll a die with the given number of sides.",
        "parameters": {
            "type": "object",
            "properties": {"sides": {"type": "integer"}},
            "required": ["sides"],
        },
    },
}]

messages = [{"role": "user", "content": "Roll a twenty-sided die for me."}]
first = client.chat.completions.create(
    model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = first.choices[0].message

if msg.tool_calls:
    messages.append(msg)
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = {"value": 17, "sides": args["sides"]}  # replace with real logic
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(result),
        })
    final = client.chat.completions.create(
        model="uncensored", messages=messages, tools=tools
    )
    print(final.choices[0].message.content)
else:
    print(msg.content)

Döngü, zar örneğinin ayrıntılarından daha önemlidir. Model bir çağrı ister, kodunuz bunu çalıştırır ve tekrar sormadan önce hem asistan mesajını hem de araç sonucunu eklersiniz. Asistan mesajını atlarsanız sonuçtaki tool_call_id ile eşleşecek bir şey olmaz ki bu genellikle kafa karıştırıcı ikinci yanıtın nedenidir. tool_choice auto olarak ayarlandığında model bir aracı çağırıp çağırmayacağına karar verir, bu nedenle yukarıdaki kodun yaptığı gibi doğrudan yanıt verdiği dalı her zaman işleyin. Akışlı yanıtlar da tool_calls taşıyabilir, parçalar halinde teslim edilirler ve argümanları ayrıştırmadan önce indeksle birleştirirsiniz.

Argümanları kullanmadan önce doğrulayın. Model bozuk bir çağrı üretebilir ve kodunuz argümanları bir kullanıcıdan gelen her şey gibi güvenilmeyen girdi olarak ele almalıdır.

Sınırlar dahilinde eşzamanlı toplu işler

Birden fazla istemi aynı anda göndermek için AsyncOpenAI ile eşzamanlılık sınırınıza uygun bir semafor kullanın. Tam anahtar 8 eşzamanlı istek, deneme anahtarı ise 2 isteğe izin verir:

import asyncio, os
from openai import AsyncOpenAI

client = AsyncOpenAI(
    base_url="https://api.glmapi.cc/v1",
    api_key=os.environ["GLM_API_KEY"],
)
gate = asyncio.Semaphore(8)  # use 2 on a trial key

async def one(prompt):
    async with gate:
        r = await client.chat.completions.create(
            model="uncensored",
            messages=[{"role": "user", "content": prompt}],
        )
        return r.choices[0].message.content

async def main():
    prompts = [f"Write a one-line tagline for product {i}." for i in range(40)]
    results = await asyncio.gather(*(one(p) for p in prompts))
    print(len(results))

asyncio.run(main())

Semafor eşzamanlılığı yönetir ancak dakika başına 300 istek sınırını yönetmez. Uzun toplu işlemler için küçük bir gecikme veya token-kova limitleyici ekleyin. 1M girdi token başı $0.15 ve 1M çıktı token başı $0.50 fiyatla, yaklaşık 60 token girdisi ve 25 token çıktısı olan 40 slogan isteği toplamda $0.00036 + $0.0005 = $0.00086 tutarında maliyet oluşturur; bu nedenle limitler, fiyat değil, toplu iş tasarımını belirler. Bakiye yüklemek için fiyatlandırma sayfasına bakın.

Hız limitleri, yeniden denemeler ve başlıklar

Bir sınırı aşarsanız API HTTP 429 döndürür. Hata kodu, dakikada çok fazla istek için rate_limited ve aynı anda çok fazla istek için concurrency'dir. Geçici aşırı yüklenme de Retry-After: 5 başlığıyla 429 döndürür. SDK bazı hataları kendi başına yeniden dener ve istemcide max_retries ayarlayabilirsiniz, ancak açık işleme daha nettir:

import time
from openai import RateLimitError

def ask(prompt, tries=4):
    for attempt in range(tries):
        try:
            raw = client.chat.completions.with_raw_response.create(
                model="uncensored",
                messages=[{"role": "user", "content": prompt}],
            )
            print("balance:", raw.headers.get("X-Balance-USD"))
            return raw.parse().choices[0].message.content
        except RateLimitError as e:
            wait = float(e.response.headers.get("Retry-After", 2 ** attempt))
            time.sleep(wait)
    raise RuntimeError("still rate limited")

Burada with_raw_response, X-Balance-USD, X-Request-Id ve hız limiti başlıklarına erişim sağlar. Rapor etmek istediğiniz herhangi bir hata ile birlikte istek kimliğini günlüğe kaydedin. Anahtarı commit ettiğiniz bir not defterine veya ön uç koduna koymayın.

Kredi harcamadan test etme ve yaygın hatalar

Python entegrasyonunun çoğu altyapıdır ve altyapının canlı bir modele ihtiyacı yoktur. Ağ çağrısını bir işlevin arkasında tutun ve testleriniz onu değiştirebilir. Yalnızca standart kütüphane ile:

from unittest.mock import MagicMock

def reply_text(client, prompt):
    r = client.chat.completions.create(
        model="uncensored",
        messages=[{"role": "user", "content": prompt}],
    )
    return r.choices[0].message.content.strip()

def test_reply_text_strips_whitespace():
    fake = MagicMock()
    fake.chat.completions.create.return_value.choices = [
        MagicMock(message=MagicMock(content="  hello  "))
    ]
    assert reply_text(fake, "hi") == "hello"

Gerçek çağrıları yalnızca uçlarda çalıştırın: her dağıtım için bir duman testi ve kayıtlı istem setinizin periyodik bir çalıştırması. Yaklaşık 100 token giriş ve 20 çıkış içeren tek bir duman testi $0.000015 + $0.00001 = $0.000025 maliyetinde olur, bu da bir şey değildir ve başarısız istekler tamamen ücretlendirilmez. $0.50 deneme kredisi bir test paketi için gerekenlerden çok daha fazlasıdır.

İstem işleri için seed ve temperature'i sabitleyin, böylece bir sistem isteminin iki sürümünü eşit koşullarda karşılaştırabilirsiniz. Çalıştırmalar arasında hem istemi hem de örnekleme ayarlarını değiştirmek sonuçları okunamaz hale getirir. Her çalıştırmanın çıktısını X-Request-Id başlığından istek kimliğiyle birlikte saklayın ve şaşırtıcı bir yanıtı daha sonra izleyebilirsiniz.

Yaygın Python hataları

Python kullanıcılarından gelen destek sorularının çoğunu bunlar oluşturur:

  • Anahtarı yalnızca OPENAI_API_KEY olarak geçirme. Kodda base_url ayarlarsanız ancak anahtar değişkenini unutursanız, SDK boş veya yanlış anahtar gönderir. api_key'i açıkça iletin.
  • /v1'i unutma. Base URL /v1 ile biter. SDK /chat/completions'i kendisi ekler.
  • Başka bir hizmetten bir model adı kullanma. Burada yalnızca uncensored geçerlidir.
  • Sınırsız eşzamanlılık. Semafor olmadan binlerce korutin üzerinde asyncio.gather çalıştırmak, concurrency hatalarından oluşan bir duvar üretir.
  • Akışlı bir yanıtı tek bir dize olarak ele alma. Delta'ları birleştirin ve boş bir choices listesi içeren parçaları atlayın.
  • Bağlam sınırını görmezden gelme. Geçmiş ve tamamlama 100.000 token içine sığmalıdır. Ona ulaşmadan önce eski mesajları kırpın.

Bakiye yüklemek ve güncel fiyat listesine bakmak için fiyatlandırma sayfasına bakın. Hizmet yalnızca metin içindir, bu nedenle bağlanacak resim, ses veya gömme çağrıları yoktur ve istemler eğitim için kullanılmaz.

Sorular ve cevaplar

Hangi Python paketine ihtiyacım var?

Standart openai paketi, sürüm 1 veya sonrası. base_url'yi https://api.glmapi.cc/v1 olarak ayarlayın ve modeli uncensored olarak ayarlayın.

Akış çalışıyor mu?

Evet. stream=True parametresini iletin ve parçalar üzerinden döngü kurun. Akış, kullanım bilgisiyle sona erer ve bitene kadar eşzamanlılık slotunu işgal eder.

Aynı anda kaç istek çalıştırabilirim?

Tam anahtar 8 eşzamanlı istek ve dakikada 300'e izin verir. Deneme anahtarı 2 ve 60'a izin verir.

LangChain veya LiteLLM kullanabilir miyim?

Her ikisi de base URL'yi, API anahtarını ve uncensored model adını verdiğinizde OpenAI-uyumlu bir uç noktayla iletişim kurabilir. Doğru parametre adları için her projenin dokümantasyonunu kontrol edin.

Anahtarınız tek bir formun uzağında

Bir hesap oluşturun, anahtarı kopyalayın ve base URL'yi değiştirin. Kurulum bu kadar basit.

API anahtarı alDokümantasyonu oku