5-qism · AI muhandisi uchun Python·23-bob
HTTP va LLM API: Python'dan Claude bilan ishlash
HTTP asoslari va httpx, REST API'ni qo'lda chaqirish, Anthropic Python SDK: so'rov va javob tuzilmasi, suhbat tarixi, streaming, xatolar va retry, tokenlar va narx, prompt caching, Pydantic bilan structured output, tool use (agent sikli), rasmlar va xavfsizlik.
Bu bob — kursning cho'qqisi: oldingi 22 bobda o'rgangan hamma narsa (satrlar, lug'atlar, funksiyalar, klasslar, xatolar, typing, Pydantic, async, fayllar) shu yerda LLM bilan ishlaydigan haqiqiy kodga aylanadi. Misollar Anthropic Claude API'sida, lekin g'oyalar (HTTP, JSON, streaming, tool use, structured output) barcha LLM provayderlari uchun bir xil.
Claude API'ni Python'dan chaqirish va amaliy misollar. Video eskiroq model (Claude 3.5) bilan yozilgan — SDK asoslari bir xil, lekin joriy model nomlari va parametrlar uchun bobga tayaning.
1. HTTP — veb-API'larning tili#
Har bir LLM API — bu HTTP so'rov: sizning dasturingiz serverga xabar yuboradi, server javob qaytaradi.
| Qism | Nima | Misol |
|---|---|---|
| Metod | Amal turi | GET (o'qish), POST (yaratish/yuborish), PUT, PATCH, DELETE |
| URL | Manzil | https://api.anthropic.com/v1/messages |
| Sarlavhalar (headers) | Metama'lumot | content-type: application/json, autentifikatsiya kaliti |
| Tana (body) | Ma'lumot (odatda JSON) | {"model": "...", "messages": [...]} |
| Status kodi | Natija | 200 OK, 400, 401, 404, 429, 500... |
Status kodlari#
| Kod | Ma'nosi | Nima qilish kerak |
|---|---|---|
| 2xx | Muvaffaqiyat | — |
| 400 | So'rov noto'g'ri (parametr, format) | Kodni tuzating — qayta urinish foydasiz |
| 401 / 403 | Kalit noto'g'ri / ruxsat yo'q | Kalitni tekshiring |
| 404 | Topilmadi (noto'g'ri URL yoki model nomi) | Tuzating |
| 408 / 429 | Vaqt tugadi / juda ko'p so'rov | Kutib qayta urinish (backoff) |
| 5xx | Server xatosi | Kutib qayta urinish |
Qoida: 4xx — sizning xatoingiz (429 dan tashqari), 5xx — server xatosi. Retry faqat vaqtinchalik xatolarda (408, 429, 5xx, tarmoq) ma'noli.
httpx bilan so'rovlar#
uv add httpximport httpx
resp = httpx.get(
"https://api.github.com/search/repositories",
params={"q": "language:python stars:>50000", "per_page": 3}, # URL'ga ?q=...&per_page=3
headers={"Accept": "application/vnd.github+json"},
timeout=10.0, # HAR DOIM timeout
)
resp.raise_for_status() # 4xx/5xx bo'lsa — httpx.HTTPStatusError
for repo in resp.json()["items"]:
print(repo["full_name"], repo["stargazers_count"])Ko'p so'rov yuboradigan kodda klient obyektini qayta ishlating — ulanishlar saqlanadi va tezroq ishlaydi:
with httpx.Client(base_url="https://api.example.com", timeout=10, headers={"Authorization": f"Bearer {token}"}) as client:
users = client.get("/users").json()
client.post("/events", json={"type": "login", "user_id": 42}) # json= — avtomatik serializatsiyaAsync versiyasi — httpx.AsyncClient (17-bob). requests kutubxonasi
ham mashhur va deyarli bir xil API'ga ega, lekin async'ni qo'llamaydi.
2. LLM API'ni qo'lda chaqirish#
SDK nima qilishini tushunish uchun avval xom HTTP so'rov:
import os
import httpx
resp = httpx.post(
"https://api.anthropic.com/v1/messages",
headers={
"x-api-key": os.environ["ANTHROPIC_API_KEY"],
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
json={
"model": "claude-opus-5-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Python'da list va tuple farqi nima? Qisqa."}],
},
timeout=60,
)
resp.raise_for_status()
data = resp.json()
print(data["content"][0]["text"])
print(data["usage"]) # {'input_tokens': ..., 'output_tokens': ...}Hammasi tanish: JSON lug'atlar, muhit o'zgaruvchisidagi kalit, timeout,
raise_for_status. Amalda esa rasmiy SDK ishlatiladi: u tiplar,
retry, streaming, xatolar klasslari va yordamchi funksiyalarni beradi.
3. Anthropic Python SDK#
uv add anthropicAPI kalitini console.anthropic.com da yarating va muhit o'zgaruvchisiga qo'ying (9-bob):
# .env
ANTHROPIC_API_KEY=sk-ant-...import anthropic
client = anthropic.Anthropic() # kalitni ANTHROPIC_API_KEY'dan o'zi o'qiydi
message = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Python'da list va tuple farqi nima? Qisqa."}],
)
for block in message.content:
if block.type == "text":
print(block.text)Javob tuzilmasi#
message.id # 'msg_01...'
message.model # 'claude-opus-5-5'
message.stop_reason # 'end_turn' | 'max_tokens' | 'tool_use' | 'refusal' | ...
message.usage # input_tokens, output_tokens, cache_read_input_tokens, ...
message.content # bloklar ro'yxati: text, thinking, tool_use...content — ro'yxat, satr emas: javobda bir nechta turdagi bloklar
bo'lishi mumkin (matn, model "fikrlashi", asbob chaqiruvi). Har doim
block.typeni tekshiring — 4-bobdagi match aynan shu uchun qulay edi.
stop_reasonni tekshiring#
| Qiymat | Ma'nosi | Reaksiya |
|---|---|---|
end_turn | Model javobni tugatdi | Normal |
max_tokens | max_tokens limitiga yetdi — javob kesilgan | Limitni oshiring yoki foydalanuvchiga bildiring |
tool_use | Model asbob chaqirmoqchi | Asbobni bajarib, natijani qaytaring (8-bo'lim) |
refusal | Xavfsizlik filtri javobni to'xtatdi | contentga tayanmang, foydalanuvchiga tushunarli xabar |
Asosiy parametrlar#
| Parametr | Ma'nosi |
|---|---|
model | Model ID'si: claude-opus-5-5 (eng kuchli, standart), claude-sonnet-5-5 (tez va arzonroq), claude-haiku-4-5 (eng tez va arzon) |
max_tokens | Javob uzunligining yuqori chegarasi (majburiy) |
messages | Suhbat: user va assistant rollari navbatma-navbat |
system | Tizim ko'rsatmasi: rol, uslub, qoidalar |
output_config={"effort": ...} | Qancha "o'ylash" — low / medium / high / xhigh / max: sifat, tezlik va narx muvozanati |
stop_sequences | Shu matn chiqsa — to'xtash |
tools | Model chaqira oladigan funksiyalar (8-bo'lim) |
4. System prompt va suhbat tarixi#
API holatsiz (stateless): har bir so'rovda butun suhbat tarixini yuborasiz. Model avvalgi xabarlarni "eslab qolmaydi" — siz ularni qayta yuborasiz:
SYSTEM = (
"Sen tajribali Python o'qituvchisisan. O'zbek tilida, qisqa va aniq javob ber. "
"Har javobda bitta kichik kod misoli bo'lsin."
)
history: list[dict] = []
def ask(question: str) -> str:
history.append({"role": "user", "content": question})
msg = client.messages.create(
model="claude-opus-5-5",
max_tokens=2048,
system=SYSTEM,
messages=history,
)
answer = "".join(b.text for b in msg.content if b.type == "text")
history.append({"role": "assistant", "content": answer})
return answer
ask("Dekorator nima?")
ask("Parametrli versiyasini ko'rsat") # model oldingi savolni "biladi" — chunki tarix yuborildiOqibatlari: suhbat uzaygan sari har so'rov qimmatlashadi (har safar
butun tarix input token sifatida hisoblanadi) va oxir-oqibat kontekst
oynasiga sig'maydi. Yechimlar: oxirgi N ta xabarni saqlash (5-bob
last_turns), eski qismni xulosa qilish, prompt caching (6-bo'lim).
5. Streaming — javobni token-token olish#
Uzun javobni to'liq tayyor bo'lishini kutish — foydalanuvchi uchun bir necha soniya "o'lik" ekran. Streaming bilan matn yozilishi bilan ko'rinadi:
with client.messages.stream(
model="claude-opus-5-5",
max_tokens=4096,
messages=[{"role": "user", "content": "Python'dagi GIL haqida tushuntir"}],
) as stream:
for text in stream.text_stream: # generator (7-bob!) — har bo'lak kelishi bilan
print(text, end="", flush=True)
final = stream.get_final_message() # to'liq Message obyekti: usage, stop_reason
print()
print(final.usage.output_tokens, final.stop_reason)Bu yerda 7-bob (generatorlar) va 14-bob (kontekst menejer) birlashdi:
with ulanishni to'g'ri yopadi, text_stream — iterator. Veb-ilovada
xuddi shu bo'laklar brauzerga uzatiladi (24-bob) — aidoc.uz'dagi
"Claude'dan so'rang" maydoni ham aynan shunday ishlaydi.
Katta max_tokens bilan ishlaganda streaming tavsiya etiladi — bitta uzun
so'rov HTTP timeout'ga uchramasligi uchun.
6. Tokenlar, narx va prompt caching#
LLM narxi tokenlar bo'yicha hisoblanadi — kiruvchi (input) va chiquvchi (output) alohida:
| Model | Input, $ / 1M token | Output, $ / 1M token |
|---|---|---|
| Claude Opus 5.5 | 4.00 | 20.00 |
| Claude Sonnet 5.5 | 2.00 | 10.00 |
| Claude Haiku 4.5 | 1.00 | 5.00 |
(2026-yil oktabr holati — narxlar o'zgarishi mumkin, rasmiy sahifani tekshiring.)
def cost_usd(usage, price_in: float = 4.0, price_out: float = 20.0) -> float:
return (usage.input_tokens * price_in + usage.output_tokens * price_out) / 1_000_000
cost_usd(message.usage) # masalan, 0.0042Yuborishdan oldin tokenlarni aniq sanash:
count = client.messages.count_tokens(
model="claude-opus-5-5",
messages=[{"role": "user", "content": long_document}],
)
count.input_tokens3-bobda aytilganidek, len(text) yoki boshqa provayderlarning
tokenizatorlari Claude tokenlarini to'g'ri bermaydi — o'zbekcha matnda
farq ayniqsa katta.
Prompt caching#
Agar har so'rovda bir xil katta qism takrorlansa (uzun tizim ko'rsatmasi, hujjat, kitob bobi), uni keshlash mumkin — keyingi so'rovlarda o'sha qism ~10 baravar arzon va tezroq o'qiladi:
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=2048,
system=[
{"type": "text", "text": "Sen hujjat bo'yicha savollarga javob beruvchi yordamchisan."},
{"type": "text", "text": big_document, "cache_control": {"type": "ephemeral"}}, # shu yergacha keshlanadi
],
messages=[{"role": "user", "content": question}],
)
response.usage.cache_creation_input_tokens # birinchi marta — keshga yozildi
response.usage.cache_read_input_tokens # keyingi so'rovlarda — keshdan o'qildiKesh prefiks bo'yicha ishlaydi: o'zgarmas qismlar oldinda, o'zgaruvchi
(savol) — oxirida. Tizim ko'rsatmasiga datetime.now() qo'shsangiz, har
so'rovda prefiks o'zgaradi va kesh hech qachon ishlamaydi.
7. Xatolar va retry#
10-bobdagi istisnolar ierarxiyasi amalda:
import anthropic
client = anthropic.Anthropic(max_retries=4, timeout=60.0) # SDK 408/429/5xx va tarmoq xatolarida o'zi qayta urinadi
try:
message = client.messages.create(model="claude-opus-5-5", max_tokens=1024, messages=msgs)
except anthropic.AuthenticationError:
raise SystemExit("API kaliti noto'g'ri — ANTHROPIC_API_KEY'ni tekshiring")
except anthropic.BadRequestError as e:
log.error("So'rov noto'g'ri: %s", e.message) # qayta urinish foydasiz — kodni tuzating
raise
except anthropic.RateLimitError:
log.warning("Limit — SDK retry'lari ham yordam bermadi")
raise
except anthropic.APIStatusError as e:
log.error("API xatosi %s: %s", e.status_code, e.message)
raise
except anthropic.APIConnectionError:
log.error("Tarmoq xatosi")
raiseTartib muhim: aniqroq klasslar oldin (RateLimitError → APIStatusError
vorisi → APIError vorisi). O'z retry siklingizni yozishdan oldin SDK'ning
max_retries parametridan foydalaning — u to'g'ri backoff va retry-after
sarlavhasini hisobga oladi.
8. Structured output — Pydantic bilan#
15-bobda Pydantic'ni shu lahza uchun o'rgangan edik. Modeldan aniq sxemadagi ma'lumot olish:
from typing import Literal
import anthropic
from pydantic import BaseModel, Field
class Review(BaseModel):
sentiment: Literal["positive", "negative", "neutral"]
topics: list[str] = Field(description="Sharhda tilga olingan mavzular, masalan: yetkazib berish, narx")
summary: str = Field(description="Bir gaplik xulosa, o'zbek tilida")
client = anthropic.Anthropic()
response = client.messages.parse(
model="claude-opus-5-5",
max_tokens=1024,
messages=[{
"role": "user",
"content": "Sharhni tahlil qil: 'Telefon zo'r, lekin yetkazib berish 2 hafta davom etdi.'",
}],
output_format=Review,
)
review = response.parsed_output # Review obyekti — tiplar tekshirilgan
review.sentiment # masalan, 'neutral'
review.topics # masalan, ['telefon sifati', 'yetkazib berish']messages.parse Pydantic modelini JSON Schema'ga aylantiradi, modelni
sxemaga mos javob berishga majburlaydi va natijani qaytadan Pydantic
obyektiga aylantiradi. 11-bobdagi extract_json kabi "mo'rt" usullarga
ehtiyoj qolmaydi. Natijani baribir mantiqan tekshiring: sxemaga mos
JSON ham noto'g'ri ma'noga ega bo'lishi mumkin.
9. Tool use — model funksiyalaringizni chaqiradi#
Tool use (function calling) — agentlarning asosi. Siz modelga funksiyalar ro'yxatini (nom, tavsif, parametrlar sxemasi) berasiz; model kerak bo'lganda "shu funksiyani shu argumentlar bilan chaqir" deydi; siz funksiyani bajarib, natijani qaytarasiz; model natijadan foydalanib javob beradi.
Mexanizmni tushunish uchun — qo'lda yozilgan agent sikli:
import json
import anthropic
client = anthropic.Anthropic()
TOOLS = [
{
"name": "get_weather",
"description": "Berilgan shahar uchun joriy ob-havoni qaytaradi.",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string", "description": "Shahar nomi, masalan: Toshkent"}},
"required": ["city"],
},
},
{
"name": "convert_currency",
"description": "Summani bir valyutadan boshqasiga o'tkazadi.",
"input_schema": {
"type": "object",
"properties": {
"amount": {"type": "number"},
"from_currency": {"type": "string", "enum": ["UZS", "USD", "EUR"]},
"to_currency": {"type": "string", "enum": ["UZS", "USD", "EUR"]},
},
"required": ["amount", "from_currency", "to_currency"],
},
},
]
RATES = {"USD": 12_650.0, "EUR": 13_900.0, "UZS": 1.0} # soxta kurslar
def get_weather(city: str) -> dict:
return {"city": city, "temp_c": 21, "condition": "quyoshli"} # haqiqiy loyihada — API chaqiruvi
def convert_currency(amount: float, from_currency: str, to_currency: str) -> dict:
result = amount * RATES[from_currency] / RATES[to_currency]
return {"result": round(result, 2), "currency": to_currency}
HANDLERS = {"get_weather": get_weather, "convert_currency": convert_currency}
def run_tool(name: str, args: dict) -> tuple[str, bool]:
"""Asbobni bajaradi. (natija_json, xatomi) qaytaradi."""
try:
return json.dumps(HANDLERS[name](**args), ensure_ascii=False), False
except Exception as e: # xatoni modelga qaytaramiz — u tuzatishga urinadi
return f"Xato: {e!r}", True
def agent(question: str, max_steps: int = 10) -> str:
messages = [{"role": "user", "content": question}]
for _ in range(max_steps): # cheksiz sikldan himoya
response = client.messages.create(
model="claude-opus-5-5", max_tokens=4096, tools=TOOLS, messages=messages,
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
return "".join(b.text for b in response.content if b.type == "text")
results = []
for block in response.content:
if block.type == "tool_use":
output, is_error = run_tool(block.name, block.input)
results.append({
"type": "tool_result",
"tool_use_id": block.id, # qaysi chaqiruvga javob ekanini bog'laydi
"content": output,
"is_error": is_error,
})
messages.append({"role": "user", "content": results}) # BARCHA natijalar bitta xabarda
raise RuntimeError("Agent qadamlar limitiga yetdi")
print(agent("Samarqandda havo qanday? Va 250 dollar necha so'm bo'ladi?"))Muhim nuqtalar:
- model bir javobda bir nechta asbobni chaqirishi mumkin — hammasini
bajarib, natijalarni bitta
userxabarida qaytaring; tool_use_id— har bir natijani o'z chaqiruviga bog'laydi;- asbob xatosini yashirmang —
is_error: Truebilan qaytaring, model ko'pincha argumentni tuzatib qayta urinadi; max_steps— cheksiz sikldan himoya (agentlar ba'zan "aylanib" qoladi).
SDK'ning tool runner'i#
Amalda bu siklni qo'lda yozish shart emas — SDK funksiyaning type hint'lari va docstring'idan (14 va 15-boblar!) sxemani o'zi yasaydi va siklni o'zi boshqaradi:
from anthropic import beta_tool
@beta_tool
def get_weather(city: str) -> str:
"""Berilgan shahar uchun joriy ob-havoni qaytaradi.
Args:
city: Shahar nomi, masalan: Toshkent.
"""
return json.dumps({"city": city, "temp_c": 21, "condition": "quyoshli"}, ensure_ascii=False)
runner = client.beta.messages.tool_runner(
model="claude-opus-5-5",
max_tokens=4096,
tools=[get_weather],
messages=[{"role": "user", "content": "Buxoroda havo qanday?"}],
)
for message in runner: # har qadamda Message; asboblar avtomatik bajariladi
for block in message.content:
if block.type == "text":
print(block.text)14-bobdagi @tool ro'yxatga oluvchi dekoratorni eslang — g'oya aynan
shu, faqat to'liq va ishlab chiqarishga tayyor.
10. Rasmlar (vision)#
import base64
from pathlib import Path
image_b64 = base64.standard_b64encode(Path("chek.jpg").read_bytes()).decode()
message = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
messages=[{
"role": "user",
"content": [
{"type": "image", "source": {"type": "base64", "media_type": "image/jpeg", "data": image_b64}},
{"type": "text", "text": "Chekdagi jami summa va sanani ayt."},
],
}],
)content satr o'rniga bloklar ro'yxati bo'lishi mumkin — matn, rasm,
hujjat (PDF) aralash. Rasm matndan oldin bo'lgani ma'qul. Bu yerni
messages.parse bilan birlashtirsangiz — cheklardan tuzilmali ma'lumot
ajratib oluvchi tizim tayyor.
11. Async va ko'p so'rov#
17-bobdagi naqsh: AsyncAnthropic + Semaphore:
import asyncio
from anthropic import AsyncAnthropic
async def summarize_all(texts: list[str], concurrency: int = 8) -> list[str]:
sem = asyncio.Semaphore(concurrency)
async with AsyncAnthropic() as client:
async def one(text: str) -> str:
async with sem:
msg = await client.messages.create(
model="claude-opus-5-5",
max_tokens=300,
output_config={"effort": "low"}, # oddiy vazifa — kam "o'ylash", tezroq va arzonroq
messages=[{"role": "user", "content": f"Bir gapda xulosa qil:\n\n{text}"}],
)
return "".join(b.text for b in msg.content if b.type == "text")
return await asyncio.gather(*(one(t) for t in texts))Natijalar darhol kerak bo'lmasa — Message Batches API (client.messages.batches):
so'rovlar paketi 24 soat ichida ~50% arzon narxda bajariladi.
12. Amaliyot: terminalda streaming chat#
Hamma narsani bitta dasturga yig'amiz — 4-bobdagi chatbot skeletining haqiqiy versiyasi:
"""chat.py — terminalda Claude bilan streaming suhbat."""
import os
import sys
import anthropic
MODEL = os.environ.get("MODEL", "claude-opus-5-5")
SYSTEM = "Sen Python bo'yicha yordamchisan. O'zbek tilida, aniq va qisqa javob ber."
MAX_TURNS = 20
PRICE_IN, PRICE_OUT = 4.0, 20.0
def main() -> None:
client = anthropic.Anthropic(max_retries=3)
history: list[dict] = []
total_cost = 0.0
print(f"{MODEL} bilan suhbat. Chiqish: Ctrl+D yoki 'chiq'.\n")
while True:
try:
user = input("Siz: ").strip()
except (EOFError, KeyboardInterrupt):
break
if not user:
continue
if user.lower() in {"chiq", "exit"}:
break
history.append({"role": "user", "content": user})
print("Claude: ", end="", flush=True)
try:
with client.messages.stream(
model=MODEL, max_tokens=4096, system=SYSTEM, messages=history[-2 * MAX_TURNS:],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final = stream.get_final_message()
except anthropic.APIError as e:
history.pop() # muvaffaqiyatsiz savolni tarixdan olib tashlaymiz
print(f"\n[xato: {type(e).__name__}] qayta urinib ko'ring.", file=sys.stderr)
continue
answer = "".join(b.text for b in final.content if b.type == "text")
if final.stop_reason == "max_tokens":
print("\n[javob uzunlik limitida kesildi]", end="")
history.append({"role": "assistant", "content": answer})
u = final.usage
cost = (u.input_tokens * PRICE_IN + u.output_tokens * PRICE_OUT) / 1e6
total_cost += cost
print(f"\n [{u.input_tokens}→{u.output_tokens} token, ${cost:.4f}]\n")
print(f"\nJami: ${total_cost:.4f}")
if __name__ == "__main__":
main()uv run chat.pyclaude-opus-5-5 bilan suhbat. Chiqish: Ctrl+D yoki 'chiq'. Siz: Generator nima, bir gapda? Claude: Generator — qiymatlarni yield orqali bittalab, faqat so'ralganda ishlab chiqaradigan funksiya; u butun ketma-ketlikni xotirada saqlamaydi. [41→38 token, $0.0009]
(Javob matni har safar biroz farq qiladi — LLM deterministik emas.)
Nima noto'g'ri ketishi mumkin#
| Xato | Oqibat | Tuzatish |
|---|---|---|
| Kalit kodda | Sizib chiqadi, pul o'g'irlanadi | Muhit o'zgaruvchisi / .env (9-bob) |
| Timeout yo'q | Osilib qolgan so'rov | Klient timeout=; uzun javoblar uchun streaming |
content[0].text | thinking yoki tool_use bloki birinchi bo'lsa — xato | block.type == "text" bo'yicha filtrlang |
stop_reason tekshirilmaydi | Kesilgan/rad etilgan javob to'liq deb qabul qilinadi | end_turn, max_tokens, refusalni ajrating |
| 400'da retry | Foydasiz so'rovlar | Faqat 408/429/5xx/tarmoq; SDK max_retries |
| Tarix cheksiz o'sadi | Narx o'sadi, kontekst to'ladi | Oxirgi N ta, xulosa, caching |
| Tizim promptida o'zgaruvchan qism | Kesh ishlamaydi | O'zgarmas qism oldinda |
temperature eng yangi modelda | 400 xato | effort |
Model JSON'iga json.loads + ishonish | Kalit yo'q, tip noto'g'ri | messages.parse + Pydantic |
| Asbob argumentlariga ko'r-ko'rona ishonish | Xavfsizlik teshigi | Validatsiya, cheklovlar, inson tasdig'i |
| Tool natijalarini alohida xabarlarda yuborish | API xatosi yoki model chalkashadi | Bitta user xabarida hammasi |
1. Xom HTTP va SDK
Bir xil savolni (a) httpx bilan xom HTTP orqali, (b) SDK orqali yuboring.
Ikkala javobdagi usageni chiqaring. Keyin ataylab xato qiling: noto'g'ri
kalit, mavjud bo'lmagan model nomi, max_tokens=5 — har birida qanday
status kodi/istisno va stop_reason chiqishini jadvalga yozing.
Maslahatni ko'rsatish
httpx.post bilan bir xil so'rovni yuboring; javob JSON'idagi usage va SDK'dagi message.usage ni solishtiring.
2. Token narxi kalkulyatori
Bir xil ma'noli inglizcha va o'zbekcha 500 so'zlik matnni count_tokens
bilan sanang (3-bob mashqining davomi). O'zbekcha matn necha foiz ko'proq
token? 10 000 ta shunday hujjatni Opus 5.5 va Haiku 4.5 bilan qayta
ishlash narxini hisoblang.
Maslahatni ko'rsatish
count_tokens bilan ikkala matnni sanang; narx = tokens * price / 1e6.
3. Structured extraction
15-bob mashqidagi ish e'loni sxemasini messages.parse bilan ishlating:
5 ta turli e'lon matnidan ma'lumot ajratib, Pandas DataFrame'ga yig'ing
va CSV'ga saqlang. Model maosh oralig'ini topa olmagan holatlarni
qanday qayta ishlaysiz?
Maslahatni ko'rsatish
class JobPost(BaseModel) — 15-bob mashqidagi sxema; messages.parse(output_format=JobPost); natijalarni pandas DataFrame'ga.
4. Kichik agent
Tool use siklini kengaytiring: (a) search_docs(query) — 11-bobdagi
JSONL fayldan kalit so'z bo'yicha qidiradi; (b) calculator(expression) —
faqat sonlar va +-*/() belgilariga ruxsat beradi (eval emas! ast
moduli bilan xavfsiz hisoblang). Har bir asbob chaqiruvini 14-bobdagi
span bilan logga yozing. Agent "hujjatlarda nechta buyurtma bor va
ularning o'rtacha narxi qancha?" kabi savolga javob bera oladimi?
- 01HTTP: metod, URL, sarlavhalar, JSON tana, status kodlari; 4xx — sizniki (429 dan tashqari), 5xx — serverniki.
- 02httpx: timeout har doim, raise_for_status, klient obyektini qayta ishlating.
- 03SDK: client.messages.create; content — bloklar ro'yxati, block.type'ni tekshiring; stop_reason'ni tekshiring.
- 04API holatsiz: suhbat tarixini har safar yuborasiz — narx va kontekst o'sadi.
- 05Streaming: with client.messages.stream(...) as s: for text in s.text_stream.
- 06Narx tokenlar bo'yicha; count_tokens bilan sanang; o'zgarmas katta qismni prompt caching bilan keshlang.
- 07Structured output: messages.parse(output_format=PydanticModel).
- 08Tool use: model so'raydi → siz bajarasiz → tool_result qaytarasiz; max_steps va xavfsizlik cheklovlari.
Mustahkamlash
Test va amaliy masalalar
Avval testni ishlang — har javobdan keyin izoh chiqadi. Keyin masalalarni shu yerning o'zida yechib, brauzerdagi haqiqiy Python bilan avtomatik tekshiring. Natijalaringiz kurs progressi sahifasida jamlanadi.
Bilimni tekshirish
Bob bo'yicha test
12 ta savol · har javobdan keyin to'g'ri yoki xatoligi va izoh ko'rsatiladi · oxirida natija foizda.
Amaliy masalalar
Kodni yozing va «Tekshirish»ni bosing (yoki Ctrl/⌘ + Enter). Kodingiz shu brauzerda saqlanib turadi.
01Javobdan matn va asboblar
split_content(content) — API javobidagi bloklar ro'yxatidan (lug'atlar) (matn, asboblar) qaytarsin: matn — barcha text bloklarining birlashmasi ("" bilan), asboblar — tool_use bloklaridan (name, input) ro'yxati. Boshqa bloklar (thinking va h.k.) e'tiborsiz.
02Agent sikli (soxta klient bilan)
run_agent(client, tools, question, max_steps=5) — client.create(messages) javob lug'atini qaytaradi: {"stop_reason": ..., "content": [...]}. stop_reason != "tool_use" bo'lsa — matnni qaytaring. Aks holda javobni assistant xabari sifatida qo'shing, har tool_use uchun tools[name](**input) ni bajarib (xato bo'lsa is_error: True va xato matni), barcha natijalarni bitta user xabarida ({"type": "tool_result", "tool_use_id": id, "content": str(natija), "is_error": bool}) qo'shing. Qadamlar tugasa — RuntimeError.
03Xarajat kalkulyatori
cost_usd(usage, model) — usage lug'ati (input_tokens, output_tokens, ixtiyoriy cache_read_input_tokens) va narxlar jadvali bo'yicha dollar narxini 6 xona yaxlitlab qaytarsin. Narxlar ($/1M): claude-opus-5-5 — 4 / 20, kesh o'qish 0.20; claude-haiku-4-5 — 1 / 5, kesh o'qish 0.10. Noma'lum model — KeyError.