Men kichkina AI agent yasadim — mana nima tushundi
Nashr etilgan 29-iyun, 2026 · 9 daqiqa o'qish
Xo'sh, bu hafta kichkina AI agent yasadim
Chatbot emas. Haqiqiy agent. Unga savol berasan, u o'zi internetda qidiradi, natijalarni o'qiydi, ko'proq qazish kerakmi deb qaror qiladi, keyin manbalar bilan birga javob yozadi. Taxminan 300 qator Python. Hech qanday murakkab narsa yo'q.
Lekin uni yasash jarayonida ko'p buzzword-lar nihoyat o'z joyiga tushdi — va men buni yozib qo'yishga qaror qildim, haqiqiy kod bilan, chunki aynan shu narsa meni tushuntirib qo'ydi. Ko'pincha o'zimga bir bezovta savol berib yurdim: nega men allaqachon biladigan narsalar bilan qurmasam?
Avval narsaning o'zini ko'rsatay, keyin uni yoyib tashlaymiz.
U ishlaganda qanday ko'rinadi
Butun app kichkina web server. Unga savol yuborasan va u nima qilayotganini qadam-baqadam stream qilib qaytaradi. Mana mening terminalimdan haqiqiy ishga tushirish:
$ curl -N "localhost:8000/research?q=Who won the 2024 Nobel Prize in Physics?"
event: searching
data: {"query": "2024 Nobel Prize in Physics winner"}
event: reading
data: {"sources": ["Press release: The Nobel Prize in Physics 2024",
"NSF congratulates the 2024 laureates", "..."]}
event: answer
data: {"text": "The 2024 Nobel Prize in Physics went to John Hopfield and
Geoffrey Hinton, for foundational work that made machine learning with
neural networks possible..."}
event: doneTartibni ko'ryapsizmi? U qidirdi, keyin o'qidi, keyin javob berdi. Qiyinroq savolda u qidirish → o'qish → qidirish → o'qish → javob deb davom etadi — qoniqarli bo'lguncha tsikl qiladi. Buni hech kim hardcode qilmagan. Shu butun sir, va bu eshitilgandan oddiyroq.
Rostini aytsam, agent bu shunchaki tsikl
Xolos. Shu sir. Marketing niqobini olib tashlasangiz, agent — bu language model atrofiga o'ralgan tsikl:
- Modelga savol yuborasan va undan foydalana oladigan tool-larni aytib berasan.
- Model ikki narsadan birini aytadi: "bu argumentlar bilan ushbu tool-ni ishga tushir" yoki "ok, mana javob."
- Agar tool so'rasa, uni ishlatasan, natijani qaytarasan va 1-qadamga qaytasan.
- Agar javob bergan bo'lsa, tugadi.
"Aqlli" qismi — model har safar: hali yetarlicha bilaman yoki ko'proq qidirish kerakmi deb qaror qilishi. Miniykiligimni kuzatganimda, u murakkab savolda ikki marta, oson savolda bir marta qidirdi — va uni necha marta qidirish kerakligi hech kimga aytilmagan. O'zi tushunib oldi. O'sha kichkina qaror? Bu butun agent. Qolgan hamma narsa — santexnika.
Lekin u Google qila olmaydi
Odamlar bilmasdan o'tadigan narsa: OpenAI API internetga kira olmaydi. Model ma'lum bir sana bo'yicha o'qitilgan va xolos — internet yo'q. O'tgan oydan biror narsa so'rasang, u yelkasini qisadi yoki ishonch bilan biror narsa to'qib chiqaradi (qiziqarli xato turi).
Shuning uchun agentga yangi ma'lumot olish uchun tool kerak. Men Tavily ishlatdim — asosan AI uchun yaratilgan qidiruv tizimi. Unga query yuborasan, u modelga o'qish uchun toza natijalar qaytaradi (sarlavha, snippet, havola) oddiy matn sifatida. Oddiy Google sizga reklama bilan to'la tartibsiz HTML sahifa berardi; Tavily esa haqiqiy kontentni beradi. Kodda bu deyarli hech narsa:
from langchain_community.tools.tavily_search import TavilySearchResults # bitta tool, top 5 natija search = TavilySearchResults(max_results=5)
Mening agentim 2024 Nobel mukofotini kim olganini ayta olganining yagona sababi shu — u qidirdi, yangi matn oldi va xulosa qildi. Bing yoki DuckDuckGo qo'yib almashtirish mumkin va hech narsa o'zgarmaydi. Bu shunchaki "haqiqatni borib olib keladigan narsa."
Asl graph
Mana o'rganishga kelgan qismim. LangGraph o'sha tsiklni boshqaradi — lekin uni graph sifatida modellashtiradi: node-lar (qadamlar) edge-lar bilan bog'langan (keyin nima bo'ladi). Mening butun agentim ikki node va bir qarordan iborat.
Birinchi, state — graphdan nimalar o'tadi. Bu uchun bu shunchaki xabarlarning joriy ro'yxati:
from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages
class State(TypedDict):
messages: Annotated[list, add_messages] # add_messages = qo'shish, ustiga yozmaslikKeyin qaror — model gapirganidan keyin qidirish kerakmi yoki tugadimi? Bu narsaning yuragi, va to'rt qator:
from langgraph.graph import END
def should_continue(state):
last = state["messages"][-1]
if getattr(last, "tool_calls", None): # model tool so'radimi?
return "tools" # -> qidirish uchun bor
return END # -> yo'q, tugadiVa keyin uni birlashtirasiz. agent node modelni chaqiradi; tools node Tavily-ni ishga tushiradi; conditional edge ularni should_continue to'xtat deguncha tsiklga tushiradi:
from langgraph.graph import StateGraph, START
from langgraph.prebuilt import ToolNode
from langchain_openai import ChatOpenAI
def build_graph():
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
tools = [TavilySearchResults(max_results=5)]
llm = llm.bind_tools(tools)
def agent(state):
return {"messages": [llm.invoke(state["messages"])]}
g = StateGraph(State)
g.add_node("agent", agent)
g.add_node("tools", ToolNode(tools))
g.add_edge(START, "agent")
g.add_conditional_edges("agent", should_continue) # agent -> toollar YOKI tugaydi
g.add_edge("tools", "agent") # toollar -> agent-ga qayt
return g.compile()Oxirgi uch qatorni ovoz chiqarib o'qing: agent-dan boshla; agent-dan keyin tarmoqlan (qidirish yoki to'xta); qidiruvdan keyin agent-ga qayt. Shu tsikl, graph sifatida chizilgan. graph.astream(...) chaqirsangiz, LangGraph undan yuradi va har bir qadamni sodir bo'lganida sizga beradi — bu aynan mening terminalimga yuqorida stream bo'lgan narsa.
Uni brauzerga stream qilish
Server qismi — bu shunchaki FastAPI har bir graph qadamini o'sha event: qatorlaridan biriga aylantiradi (Server-Sent Events). Qisqacha:
async def run_agent(question):
graph = build_graph()
inputs = {"messages": [("user", question)]}
async for step in graph.astream(inputs, stream_mode="updates"):
# step bu {node_name: {...}} — searching/reading/answer-ga aylantir
yield to_sse(step)Kichkina HTML sahifa o'sha stream-ni tinglab jonli ravishda timelineni chizadi, shuning uchun foydalanuvchi spinner-ga qarab o'tirmaydi va agentning o'ylashini kuzatadi. Bu qism eshitilganidan ko'ra muhimroq — "ishingni ko'rsat" sababining yarmi narsaning ishonchli his qilinishida.
Xo'sh, LangGraph nima uchun kerak?
Bu yerda o'zimga rostini aytishim kerak edi. O'sha tsiklga qarang. Bu chiroyli va tartibli... lekin qo'lda, hech qanday framework-siz yozilganda, bu taxminan o'n besh qator:
let messages = [systemPrompt, userQuestion]
while (true) {
const reply = await openai.chat(messages, { tools: [search] })
messages.push(reply)
if (reply.toolCalls) {
for (const call of reply.toolCalls)
messages.push(await runSearch(call)) // qidirish, natijalarni qaytarish
} else {
return reply.content // model tugadi
}
}Bitta tool va oddiy tsikl uchun o'sha oddiy while loop haqiqatan ham yaxshi. Hatto engil. O'rganish uchun framework yo'q. Xo'sh... nega men LangGraph-ga qo'l uzatdim?
"Nega Next.js va OpenAI emas?"
Ha, men bu savolni doim aylanib yurdim, va u yaxshi savol — lekin unda kichkina tuzoq bor. Next.js va LangGraph raqobat qilmaydi. Ular bir javonda ham emas:
- Next.js — app, UI va server. Bu men ishlatgan FastAPI + HTML-ni almashtiradi, LangGraph-ni emas.
- OpenAI — miya.
- Tavily — web tool — uni har qanday holatda ham ishlatish kerak.
- LangGraph — tsikl — aks holda o'zingiz yozadigan qism.
Shuning uchun "Next.js + OpenAI" demoq: app uchun Next.js, miya uchun OpenAI, va tsiklni o'zingiz yozasiz. Va mening kichkina demo uchun? Bu ishlagan bo'lardi va oddiyroq bo'lardi. Buni boshqacha ko'rsatmayman.
Xo'sh, framework qachon haqiqatan ham o'zini qoplaydi?
LangGraph birinchi feature-da emas, ikkinchi va uchinchisida o'zini ko'rsata boshlaydi — tsikl toza while loop bo'lishdan to'xtaganda:
- Ko'p tool-lar bilan tarmoqlanish — "matematik savol bu yerga, qidirish u yerga, ma'lumotlar bazasi lookup narigi yerga." Bu graph-da bir toza edge, yoki o'z tsiklingizda o'sib borayotgan ichma-ich
if-lar to'plami. - Qayta ishga tushirishdan omon qoladigan xotira — state-ni ma'lumotlar bazasiga saqlash, insonning biror narsani tasdiqlashi uchun o'rtada to'xtatish, keyin davom ettirish. Bu katta narsa. Buning o'z versiyasini qo'lda yozish tez orada xunuk bo'lib qoladi.
- Har bir qadamni stream qilish — Men
searching → reading → answerprogresini deyarli bepul oldim. - Ko'p agent-lar — researcher yozuvchiga ish topshiradi, har biri o'zining graph-i.
Qisqasi: bitta tool va to'g'ri tsikl? Tsiklni yozib qo'ya qoling. Mijoz "besh tool ishlatiladigan, butun suhbatni eslab turadigan, biror narsani qimmatroq qilishdan oldin men bilan maslahatlashadigan agent yasib ber" degan kun — aynan o'sha kuni qo'lda yozilgan narsingiz spaghetti-ga aylanadi, va graph o'qilishi mumkin bo'lib qoladi.
O'zingiz sinab ko'rmoqchimisiz?
Butun narsa haqiqatan ham kichkina. OpenAI kalitingiz va (bepul) Tavily kalitingiz bo'lsa, taxminan ikki daqiqalik sozlash:
python -m venv venv && source venv/bin/activate pip install langgraph langchain-openai langchain-community fastapi uvicorn python-dotenv # kalitlarni .env-ga yozib qo'y echo "OPENAI_API_KEY=sk-..." >> .env echo "TAVILY_API_KEY=tvly-..." >> .env uvicorn main:app --reload --port 8000
Va loyiha tuzilishi iloji boricha tekis — src/ labirinti yo'q, o'n ikki config fayli yo'q:
research-agent/ graph.py # LangGraph agent (state, node-lar, tsikl) main.py # FastAPI + SSE streaming index.html # jonli timelineni chizuvchi kichkina UI .env # ikki kalit
localhost:8000-ni oching, yaqinda bo'lgan biror narsa so'rang va uni qidirishini kuzating. Birinchi marta u o'z-o'zidan ikki marta tsikl qilib javobni aniqlaganda, bu "qo'shimcha qadamlar bilan OpenAI" kabi his qilishdan to'xtaydi va haqiqatan ham kerakli narsani o'ylab topayotgan kichkina narsa kabi his qila boshlaydi.
Nega men bu kichkina narsaga vaqt sarfladim
Men biror loyiha agentlarga majburlagunicha kutishim mumkin edi. Xohlamadim. Bir narsani oson muammoda o'rganish uni dahshatli versiyasi paydo bo'lganda allaqachon tanish qilishini anglatadi — va Upwork-da "X, Y va Z qiladigan AI agent yasib ber" so'rovi endi taxminan har oy kelib turadi. Shuning uchun haqiqiy bittasi tushganida, men tool va muammoni bir vaqtda tushunishga harakat qilmayman.
Bu dam olish kuni loyihasining butun mohiyati, rostini aytsam. O'quv solig'ini hech narsa risk ostida bo'lmaganda to'la — keyin uni muhim bo'lganda ishlatish uchun chek saqla.