ID ▾
Dapatkan kunci API

Contoh Python API GLM: Chat, Streaming, dan Tools

Untuk pekerjaan python api glm, Anda hanya memerlukan paket openai standar: arahkan ke https://api.glmapi.cc/v1, gunakan ID model uncensored, dan panggilan chat biasa berfungsi. Halaman ini membahas setiap pola dengan kode yang dapat Anda jalankan, mulai dari permintaan pertama hingga batch asinkron dan penanganan batas laju.

Poin utama

  • Instal openai, atur base_url ke https://api.glmapi.cc/v1 dan gunakan model uncensored.
  • Streaming, mode JSON, dan pemanggilan alat menggunakan parameter yang sama dengan API chat OpenAI.
  • Kunci penuh mengizinkan 8 permintaan konkuren dan 300 per menit, jadi batasi pekerja asinkron Anda hingga 8.
  • Tangani 429 dengan membaca kode kesalahan dan header Retry-After.
Pita aliran data streaming dari terminal laptop ke server cloud, mewakili panggilan API Python

Instal dan permintaan pertama

Buat lingkungan virtual dan instal SDK. Versi 1 atau lebih baru dari paket openai diasumsikan di seluruh halaman.

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

Dapatkan kunci dari halaman kunci API; pengguna baru dapat mengklaim uji coba senilai $0,50 dengan satu klik, berlaku selama 7 hari dan tanpa kartu. Simpan kunci dalam variabel lingkungan, lalu buat panggilan pertama:

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)

Itulah seluruh integrasi. Layanan ini adalah endpoint yang kompatibel dengan OpenAI untuk satu model bobot terbuka, sehingga ini bukan API resmi dari vendor di balik GLM atau pihak lain. Hanya POST /v1/chat/completions dan GET /v1/models yang ada. Panduan awal mencantumkan bidang permintaan yang didukung.

Dua kebiasaan kecil membantu sejak awal. Pertama, panggil client.models.list() sekali dalam smoke test: ini mengakses GET /v1/models, sehingga membuktikan bahwa kunci, base URL, dan jalur jaringan semuanya berfungsi sebelum Anda menghabiskan satu token pun untuk penyelesaian. Kedua, cetak resp.usage selama pengembangan. Hitungan token prompt dan penyelesaian menunjukkan kepada Anda apakah prompt sistem lebih besar dari yang Anda kira, dan pada $0,15 per 1 juta input dan $0,50 per 1 juta output, Anda dapat memperkirakan biaya panggilan di kepala Anda.

Chat multi-gilir dan pengaturan sampling

API ini stateless, jadi Anda menyimpan daftar percakapan sendiri dan mengirimkannya setiap kali. Kelas kecil sudah cukup:

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

Potongan self.history[-self.max_turns * 2:] menyimpan dua belas pasangan pengguna dan asisten terakhir. Aplikasi nyata mungkin juga mengunci beberapa pesan awal, seperti lembar karakter atau fakta kunci, dan meringkas bagian tengah. Memotong hingga 12 putaran terakhir menjaga biaya input tetap stabil seiring pertumbuhan percakapan. Jendela konteks adalah 100.000 token untuk prompt dan completion bersama-sama, jadi ini adalah pilihan biaya lebih daripada kebutuhan. Parameter temperature, top_p, stop, seed dan penalti diteruskan. Atur seed saat Anda ingin menjalankan ulang yang dapat direproduksi saat menguji prompt, dan biarkan max_tokens tidak diatur kecuali Anda ingin membatasi panjangnya.

Respons streaming

Streaming menggunakan server-sent events dan memberikan token kepada Anda saat dihasilkan, yang penting untuk alat interaktif. Berikan stream=True dan iterasi:

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)

Pemeriksaan pada chunk.choices penting karena chunk terakhir membawa penggunaan dan mungkin memiliki daftar choices kosong. Satu poin operasional: permintaan yang dialirkan memegang slot konkurensinya hingga stream berakhir. Bungkus loop dalam blok try dengan klausa finally yang menutup stream jika kode Anda menimbulkan kesalahan di tengah jalan, misalnya ketika klien terputus. Selalu selesaikan atau tutup stream, jika tidak loop yang meninggalkan stream akan mencapai batas konkurensi sambil melakukan pekerjaan yang tidak berguna.

Mode JSON

Ketika output menjadi masukan bagi kode lain, minta objek JSON. Sebutkan JSON dalam prompt juga, agar model mengetahui bentuk yang Anda harapkan:

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"])

Tetap bungkus json.loads dalam blok try dalam kode produksi. Mode JSON membuat output yang valid menjadi lebih mungkin, dan permintaan yang terpotong oleh urutan berhenti atau batas Anda sendiri masih dapat meninggalkan objek yang terpotong. Mencoba lagi sekali dengan input yang sama adalah perbaikan murah, dan karena permintaan yang gagal tidak dibebankan biaya, biaya percobaan ulang hanyalah panggilan yang berhasil.

Pemanggilan alat

Pemanggilan alat mengikuti bentuk OpenAI: Anda mendeskripsikan fungsi dalam tools, model mengembalikan tool_calls, Anda menjalankannya dan mengirimkan kembali hasil dengan role tool. Perjalanan bolak-balik lengkap:

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)

Loop lebih penting daripada detail dadu. Model meminta panggilan, kode Anda menjalankannya, dan Anda menambahkan pesan asisten dan hasil alat sebelum meminta lagi. Jika Anda melewatkan pesan asisten, tool_call_id dalam hasil tidak akan memiliki pasangan yang cocok, yang merupakan penyebab umum balasan kedua yang bingung. Dengan tool_choice diatur ke auto model memutuskan apakah akan memanggil alat sama sekali, jadi selalu tangani cabang di mana ia menjawab langsung, seperti yang dilakukan kode di atas. Respons yang dialirkan dapat membawa tool_calls juga, yang dikirimkan dalam potongan yang Anda gabungkan berdasarkan indeks sebelum menguraikan argumennya.

Validasi argumen sebelum bertindak. Model dapat menghasilkan panggilan yang tidak valid, dan kode Anda harus memperlakukan argumen sebagai input yang tidak dipercaya, sama seperti apa pun dari pengguna.

Batch asinkron dalam batas

Untuk banyak prompt sekaligus, gunakan AsyncOpenAI dengan semaphore yang sesuai dengan batas konkurensi Anda. Kunci penuh mengizinkan 8 permintaan konkuren, kunci uji coba 2:

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())

Semaphore menangani konkurensi tetapi bukan batas per menit 300 permintaan. Untuk batch panjang, tambahkan jeda kecil atau pembatas token-bucket. Pada $0,15 per 1 juta token input dan $0,50 per 1 juta token output, 40 permintaan slogan dengan sekitar 60 token masuk dan 25 keluar per permintaan menelan biaya $0,00036 + $0,0005 = $0,00086 secara total, jadi batas, bukan harga, membentuk desain batch. Lihat halaman harga untuk top-up.

Batas laju, percobaan ulang, dan header

Di atas batas, API mengembalikan HTTP 429. Kode kesalahan adalah rate_limited untuk terlalu banyak permintaan per menit dan concurrency untuk terlalu banyak sekaligus. Beban berlebih sementara juga mengembalikan 429 dengan header Retry-After: 5. SDK mencoba lagi beberapa kegagalan secara mandiri dan Anda dapat mengatur max_retries pada klien, tetapi penanganan eksplisit lebih jelas:

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")

Di sini with_raw_response memberikan akses ke X-Balance-USD, X-Request-Id dan header batas laju. Log ID permintaan dengan kesalahan apa pun yang ingin Anda laporkan. Jangan masukkan kunci ke notebook yang Anda komit atau ke kode front-end.

Pengujian tanpa menghabiskan saldo prabayar, dan kesalahan umum

Sebagian besar integrasi Python adalah kode penghubung, dan kode penghubung tidak memerlukan model langsung. Simpan panggilan jaringan di balik satu fungsi, dan pengujian Anda dapat menggantinya. Hanya dengan pustaka standar:

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"

Jalankan sejumlah panggilan nyata hanya di tepi: satu smoke test per deploy, ditambah menjalankan secara berkala set prompt yang Anda simpan. Satu smoke test dengan sekitar 100 token masuk dan 20 keluar biaya $0,000015 + $0,00001 = $0,000025, yang tidak ada apa-apanya, dan permintaan yang gagal tidak dibebankan biaya sama sekali. Kredit uji coba $0,50 jauh lebih banyak daripada yang dibutuhkan oleh suite pengujian.

Untuk pekerjaan prompt, tetapkan seed dan temperature agar Anda dapat membandingkan dua versi prompt sistem dalam kondisi yang setara. Mengubah prompt dan pengaturan pengambilan sampel antara menjalankan ulang membuat hasil sulit dibaca. Simpan output setiap menjalankan ulang dengan ID permintaan dari header X-Request-Id, dan Anda dapat melacak jawaban yang mengejutkan nanti.

Kesalahan Python umum

Ini menyebabkan sebagian besar pertanyaan dukungan yang berasal dari pengguna Python:

  • Meneruskan kunci sebagai OPENAI_API_KEY saja. Jika Anda mengatur base_url dalam kode tetapi lupa variabel kunci, SDK mengirimkan kunci kosong atau salah. Teruskan api_key secara eksplisit.
  • Melupakan /v1. Base URL berakhir dengan /v1. SDK menambahkan /chat/completions sendiri.
  • Menggunakan nama model dari layanan lain. Hanya uncensored yang valid di sini.
  • Konkurensi tak terbatas. asyncio.gather lebih dari seribu koroutine tanpa semaphore menghasilkan dinding kesalahan concurrency.
  • Memperlakukan balasan yang dialirkan sebagai satu string. Gabungkan delta, dan lewati chunk dengan daftar choices kosong.
  • Mengabaikan batas konteks. Riwayat plus completion harus muat dalam 100.000 token. Potong putaran lama sebelum Anda mencapainya.

Untuk top-up dan daftar harga saat ini, lihat halaman harga. Layanan ini hanya teks, jadi tidak ada panggilan gambar, audio, atau embedding untuk dipasang, dan prompt tidak digunakan untuk pelatihan.

Tanya jawab

Paket Python apa yang saya butuhkan?

Paket openai standar, versi 1 atau lebih tinggi. Atur base_url ke https://api.glmapi.cc/v1 dan model ke uncensored.

Apakah streaming berfungsi?

Ya. Berikan stream=True dan iterasi melalui potongan data. Aliran berakhir dengan informasi penggunaan, dan ia menempati slot konkurensi hingga selesai.

Berapa banyak permintaan yang dapat saya jalankan secara paralel?

Kunci penuh mengizinkan 8 permintaan paralel dan 300 per menit. Kunci uji coba mengizinkan 2 dan 60.

Bisakah saya menggunakan LangChain atau LiteLLM sebagai gantinya?

Keduanya dapat berkomunikasi dengan endpoint yang kompatibel dengan OpenAI ketika Anda memberikan base URL, kunci, dan nama model uncensored. Periksa dokumentasi setiap proyek untuk nama parameter yang tepat.

Kunci Anda hanya selangkah lagi dari satu formulir

Buat akun, salin kunci, ubah URL dasar. Itu saja seluruh proses pengaturannya.

Dapatkan kunci APIBaca dokumentasi