course
Kimi K2.6 este cel mai nou model open-source de la Moonshot AI, conceput pentru programare, execuții pe termen lung, utilizarea de instrumente și fluxuri de lucru pentru agenți. Modelul este disponibil prin Kimi.com, aplicația Kimi, Kimi Code și API, fiind util pentru a construi aplicații AI practice care au nevoie de raționare, apeluri de instrumente și rezultate structurate.
În acest tutorial, veți construi JobFit AI, un asistent AI pentru căutarea de joburi care citește CV-ul unui candidat, caută anunțuri active, verifică pagini de job selectate și generează un raport de potrivire ierarhizat. Kimi K2.6 se potrivește bine acestui proiect deoarece acceptă fluxuri cu context extins, apeluri de instrumente și atât moduri cu gândire, cât și fără gândire, prin platforma API Kimi.
Proiectul folosește:
- Kimi K2.6 ca model de raționare
- Olostep pentru căutare web în timp real și scraping al paginilor de job
- pypdf pentru a extrage text din CV-ul candidatului
- OpenAI Agents SDK pentru a construi agentul care folosește instrumente
- Gradio pentru a transforma fluxul într-o aplicație web simplă
La finalul acestui tutorial, veți avea o aplicație funcțională care permite utilizatorilor să încarce un CV, să își descrie preferințele de job și să genereze în mai puțin de un minut un raport ierarhizat al joburilor relevante.
Dacă abia începeți cu AI agentic, vă recomand cu tărie să vă înscrieți la traseul de competențe Fundamentele agenților AI. Acesta acoperă toate bazele privind modelele de proiectare, MCP și sistemele multi-agent.
Cerințe preliminare pentru tutorial
Înainte de a începe, asigurați-vă că aveți:
- Python 3.11+
- O cheie API Kimi
- Cel puțin 5 $ credit în contul dumneavoastră Moonshot AI
- O cheie API Olostep
- Un CV în format PDF
- Cunoștințe de bază de Python
1. Configurați mediul Python
Creați un nou folder de proiect:
mkdir JobFit-AI
cd JobFit-AI
Apoi instalați pachetele necesare:
pip install gradio openai pypdf openai-agents
Pachetele principale sunt:
-
gradio: creează interfața web -
openai: se conectează la API-uri compatibile cu OpenAI -
pypdf: extrage text din fișiere PDF -
openai-agents: creează agentul AI care utilizează instrumente
În continuare, creați conturi și generați cheile API:
- Creați un cont gratuit Olostep și generați o cheie API din tabloul de bord Olostep. Vă puteți înscrie și la planul Starter la 9 $/lună, care include 5.000 de cereri. Acest lucru vă oferă suficiente cereri pentru a testa și lansa aplicația.
- Accesați platforma Kimi, adăugați cel puțin 5 $ credit și generați cheia API.
Setați cheile API Kimi și Olostep ca variabile de mediu. MOONSHOT_API_KEY este folosită pentru a accesa API-ul Kimi K2.6, iar OLOSTEP_API_KEY este folosită pentru a căuta și a face scraping pe pagini de job active.
2. Definiți configurația proiectului
Lansați Jupyter Notebook, creați o celulă nouă și adăugați importurile necesare și configurația proiectului.
import json
import os
import requests
from agents import Agent, AsyncOpenAI, ModelSettings, OpenAIChatCompletionsModel, RunConfig, Runner, function_tool, set_tracing_disabled
from IPython.display import Markdown, display
from pypdf import PdfReader
Acum definiți numele modelului, endpoint-urile API, numărul maxim de ture ale agentului, calea către CV și preferințele de job.
KIMI_MODEL = "kimi-k2.6"
KIMI_BASE_URL = "https://api.moonshot.ai/v1"
OLOSTEP_SEARCH_URL = "https://api.olostep.com/v1/searches"
OLOSTEP_SCRAPE_URL = "https://api.olostep.com/v1/scrapes"
MAX_AGENT_TURNS = 25
cv_path = "abid-resume.pdf"
preferences = """
Remote data science, AI writer, or technical writer roles in AI, machine learning, data science, or cloud.
Prefer technical content, tutorials, developer education, research writing, and AI product storytelling.
""".strip()
set_tracing_disabled(True)
Valorile KIMI_MODEL și KIMI_BASE_URL indică aplicației să folosească Kimi K2.6 prin endpoint-ul compatibil cu OpenAI al Moonshot AI. URL-urile Olostep sunt folosite pentru căutarea de joburi în timp real și scraping de pagini.
Variabila cv_path indică către PDF-ul CV-ului candidatului. Asigurați-vă că PDF-ul este salvat în același folder al proiectului sau actualizați calea dacă este stocat în altă parte.
Variabila preferences îi spune agentului ce tip de joburi să caute. O puteți actualiza în funcție de rolul țintă, industrie, locație, nivel de senioritate sau stil de lucru preferat.
Dezactivăm tracing cu set_tracing_disabled(True) deoarece tracing este o funcționalitate din OpenAI Agents SDK activată implicit. Cum acest proiect folosește Kimi printr-un endpoint compatibil OpenAI, dezactivarea tracing simplifică setarea locală și evită problemele legate de tracing cu un furnizor terț de modele.
3. Conectați-vă la API-ul Kimi K2.6
Apoi, configurați clientul Kimi folosind cheia API salvată anterior ca variabilă de mediu.
kimi_client = AsyncOpenAI(
api_key=os.environ["MOONSHOT_API_KEY"],
base_url=KIMI_BASE_URL,
)
Aceasta creează clientul API pentru Kimi. api_key este încărcată din MOONSHOT_API_KEY, iar base_url indică către endpoint-ul compatibil cu OpenAI al Moonshot AI.
În continuare, înfășurați modelul Kimi pentru a putea fi folosit în OpenAI Agents SDK:
kimi_model = OpenAIChatCompletionsModel(
model=KIMI_MODEL,
openai_client=kimi_client,
)
Acum definiți setările modelului:
model_settings = ModelSettings(
tool_choice="auto",
parallel_tool_calls=True,
extra_body={"thinking": {"type": "disabled"}},
)
Setarea tool_choice="auto" permite agentului să decidă când să apeleze instrumentele. parallel_tool_calls=True permite agentului să ruleze simultan mai multe apeluri de instrumente, atunci când este necesar.
De asemenea, dezactivăm modul de gândire al lui Kimi folosind extra_body={"thinking": {"type": "disabled"}}. Acest lucru păstrează rezultatul mai curat și mai potrivit pentru un raport structurat de potrivire.
În final, creați configurația de rulare:
run_config = RunConfig(
workflow_name="JobFit AI Kimi Search",
tracing_disabled=True,
)
workflow_name oferă acestei rulari o etichetă clară. Menținem tracing dezactivat și aici deoarece acest proiect folosește Kimi printr-un endpoint compatibil OpenAI, nu backend-ul de tracing al OpenAI.
4. Extrageți text din CV-ul candidatului
În continuare, folosiți PdfReader pentru a încărca CV-ul candidatului și a extrage textul din fiecare pagină.
reader = PdfReader(cv_path)
cv_text = "\n".join(page.extract_text() or "" for page in reader.pages)[:12000]
print(f"Loaded {len(cv_text):,} characters from {cv_path}")
Acest cod citește fișierul PDF definit în cv_path, extrage textul din fiecare pagină și îl combină într-un singur șir.
Limita [:12000] menține textul CV-ului suficient de scurt pentru a încăpea confortabil în promptul agentului, oferind totodată modelului suficient context despre experiența, abilitățile și preferințele candidatului.
Ieșirea va arăta similar cu aceasta, în funcție de numele și lungimea fișierului dumneavoastră de CV:
Loaded 2,946 characters from abid-resume.pdf
Aceasta confirmă că CV-ul a fost încărcat cu succes și arată câte caractere au fost extrase din PDF.
5. Creați instrucțiunile agentului
În continuare, definiți instrucțiunile care controlează modul în care agentul trebuie să caute, să folosească instrumentele și să formateze raportul final.
AGENT_INSTRUCTIONS = """
You are JobFit AI, a focused job-search agent.
Tool plan:
- Call search_jobs exactly once with limit 8.
- Read at most 3 direct job pages with read_job_page.
- After reading up to 3 pages, stop using tools and write the report.
- Search again only if the first search returns zero usable jobs.
- Avoid broad search pages, expired jobs, and LinkedIn unless no better source exists.
Report rules:
- Keep the report simple, clear, and practical.
- Use short bullets.
- Do not use em dashes.
- Do not use contractions.
- Do not add text before or after the report.
- End after the final Job Notes entry.
- Include at least 5 ranked jobs if the search results contain at least 5 usable jobs.
- If only 3 pages were scraped, use backup jobs from search results when they look usable.
- Every job must include a clickable Markdown link.
- Every job must have one apply decision: Apply, Maybe, or Do not apply.
Use exactly this Markdown structure:
# JobFit AI Report
## Best Match
- **Role:** <job title>
- **Company:** <company>
- **Apply decision:** Apply / Maybe / Do not apply
- **Fit score:** <score>/100
- **Link:** [Apply here](<job url>)
**Why this is the best match:**
- <specific reason>
- <specific reason>
- <specific reason>
## Ranked Jobs
| Rank | Role | Company | Apply? | Fit | Link |
| --- | --- | --- | --- | --- | --- |
| 1 | <role> | <company> | Apply / Maybe / Do not apply | <score>/100 | [Apply here](<url>) |
## Job Notes
### 1. <Role> at <Company>
- **Apply decision:** Apply / Maybe / Do not apply
- **Fit score:** <score>/100
- **Link:** [Apply here](<job url>)
**Why it fits:**
- <bullet>
- <bullet>
**Concerns:**
- <bullet>
- <bullet>
**Application angle:**
- <how the person should position their CV/application>
""".strip()
Aceste instrucțiuni mențin agentul concentrat. Ele limitează fluxul de lucru la o singură căutare de job, până la trei citiri de pagini de job și o structură fixă a raportului în Markdown.
Regulile raportului fac, de asemenea, rezultatul mai ușor de parcurs, cerând puncte scurte, linkuri clicabile, scoruri de potrivire și o decizie clară de aplicare pentru fiecare rol.
6. Construiți promptul de runtime
După definirea instrucțiunilor agentului, creați șablonul de prompt care va fi transmis agentului la fiecare rulare.
RUN_PROMPT_TEMPLATE = """
Find current job postings for this candidate and rank them by fit.
Keep the run simple:
- one search
- up to three page reads
- final report
The final report must follow AGENT_INSTRUCTIONS exactly.
Use simple wording. Do not use em dashes. Do not use contractions.
Candidate CV:
{cv_text}
Preferences:
{preferences}
""".strip()
Acest prompt combină textul CV-ului candidatului și preferințele de job la runtime.
Placeholder-ul cv_text este completat cu conținutul extras din CV, în timp ce preferences este completat cu preferințele pentru rolul țintă definite anterior. Împreună, oferă agentului suficient context pentru a căuta joburi relevante și a le ierarhiza după potrivire.
7. Adăugați căutare web în timp real cu Olostep
Acum că instrucțiunile agentului și promptul de runtime sunt gata, adăugați două instrumente care îi permit agentului să caute pe web și să citească pagini de job folosind Olostep.
Primul instrument caută pe web anunțuri de job și returnează o listă compactă de rezultate.
@function_tool
def search_jobs(query: str, limit: int = 8) -> str:
"""Search the web for job listings and return compact JSON results."""
response = requests.post(
OLOSTEP_SEARCH_URL,
headers={"Authorization": f"Bearer {os.environ['OLOSTEP_API_KEY']}", "Content-Type": "application/json"},
json={"query": query},
timeout=60,
)
response.raise_for_status()
links = response.json().get("result", {}).get("links", [])[:limit]
results = [
{"title": item.get("title", "Untitled"), "url": item.get("url"), "description": item.get("description", "")}
for item in links
if isinstance(item, dict) and item.get("url")
]
return json.dumps(results, ensure_ascii=False)
Decoratorul @function_tool face ca această funcție Python să fie disponibilă agentului ca instrument apelabil.
Când agentul are nevoie de anunțuri de job, apelează search_jobs cu o interogare de căutare. Funcția trimite interogarea la endpoint-ul de căutare Olostep, colectează rezultatele de top și le returnează ca JSON.
Fiecare rezultat include:
- titlul jobului
- URL-ul jobului
- descriere scurtă
Al doilea instrument permite agentului să deschidă și să citească o pagină specifică de job.
@function_tool
def read_job_page(url: str) -> str:
"""Scrape one job listing URL and return markdown text."""
response = requests.post(
OLOSTEP_SCRAPE_URL,
headers={"Authorization": f"Bearer {os.environ['OLOSTEP_API_KEY']}", "Content-Type": "application/json"},
json={"url_to_scrape": url, "formats": ["markdown"]},
timeout=120,
)
response.raise_for_status()
markdown = response.json().get("result", {}).get("markdown_content") or ""
return markdown[:8000]
Această funcție trimite un URL de job către endpoint-ul de scraping Olostep și returnează conținutul paginii în format Markdown.
Limita [:8000] menține pagina extrasă suficient de scurtă pentru a fi procesată de agent, capturând în același timp detaliile cele mai utile ale jobului, precum responsabilități, cerințe și informații despre companie.
8. Creați agentul JobFit AI
Acum creați agentul și conectați toate piesele definite anterior: modelul Kimi, setările modelului, instrumentele Olostep și instrucțiunile agentului.
agent = Agent(
name="JobFit AI",
model=kimi_model,
model_settings=model_settings,
tools=[search_jobs, read_job_page],
instructions=AGENT_INSTRUCTIONS,
)
Obiectul Agent este controlerul principal al acestui flux de lucru.
El folosește:
kimi_modelca model de raționaremodel_settingspentru a controla utilizarea instrumentelor și comportamentul ieșiriisearch_jobspentru a găsi anunțuri de job în timp realread_job_pagepentru a face scraping pe pagini de job selectateAGENT_INSTRUCTIONSpentru a respecta exact regulile de căutare și de raport
În acest punct, agentul este gata să caute joburi, să le compare cu CV-ul candidatului și să genereze un raport structurat JobFit AI.
9. Rulați fluxul de lucru al agentului
Acum rulați agentul JobFit AI folosind textul extras din CV și preferințele de job definite anterior.
Mai întâi, formatați promptul de runtime:
prompt = RUN_PROMPT_TEMPLATE.format(cv_text=cv_text, preferences=preferences)
Acesta completează șablonul de prompt cu CV-ul candidatului și preferințele pentru jobul țintă.
În continuare, porniți rularea agentului cu streaming:
print("Starting agent run")
result = Runner.run_streamed(
agent,
prompt,
max_turns=MAX_AGENT_TURNS,
run_config=run_config,
)
Metoda Runner.run_streamed() pornește fluxul de lucru al agentului și transmite evenimentele pe măsură ce se întâmplă. Astfel, este mai ușor să vedeți când agentul apelează un instrument, primește outputul și creează mesajul final.
Acum adăugați bucla de streaming:
async for event in result.stream_events():
if event.type == "agent_updated_stream_event":
print(f"Agent: {event.new_agent.name}")
elif event.type == "run_item_stream_event":
item = event.item
if event.name == "tool_called":
raw = item.raw_item
tool_name = raw.get("name") if isinstance(raw, dict) else getattr(raw, "name", "tool")
arguments = raw.get("arguments") if isinstance(raw, dict) else getattr(raw, "arguments", "")
arguments = str(arguments).replace(chr(10), " ")[:500]
print(f"Tool call: {tool_name}")
if arguments:
print(f"Parameters: {arguments}")
elif event.name == "tool_output":
print(f"Tool output: {len(str(item.output)):,} chars")
elif event.name == "message_output_created":
print("Final message ready")
Această buclă tipărește actualizări utile ale progresului în timpul rulării agentului. De exemplu, arată când agentul caută joburi, citește o pagină de job sau finalizează generarea raportului.
În final, salvați ieșirea finală într-o variabilă numită report:
report = result.final_output
globals()["report"] = report
print("Run complete")
print(f"Model responses: {len(result.raw_responses)}")
print(f"Run items: {len(result.new_items)}")
print(f"Final output: {len(str(report)):,} chars")
Variabila report stochează raportul final JobFit AI, pe care îl puteți afișa, salva sau utiliza în aplicația Gradio.
Ieșirea arată astfel:
Starting agent run
Agent: JobFit AI
Tool call: search_jobs
Parameters: {"query":"remote data science writer technical writer AI machine learning content editor","limit":8}
Tool output: 2,445 chars
Tool call: read_job_page
Parameters: {"url":"https://www.indeed.com/q-data-science-writer-jobs.html"}
Tool output: 8,000 chars
Tool call: read_job_page
Parameters: {"url":"https://www.builtinnyc.com/jobs/remote/data-analytics/data-science"}
Tool output: 8,000 chars
Tool call: read_job_page
Parameters: {"url":"https://www.virtualvocations.com/jobs/q-data+scientist+remote+jobs/c-writing/d-336"}
Tool output: 5,075 chars
Final message ready
Run complete
Model responses: 5
Run items: 13
Final output: 5,931 chars
Această ieșire confirmă că agentul a căutat joburi, a citit pagini selectate și a generat cu succes raportul final.
10. Afișați raportul JobFit generat
După ce rularea agentului este completă, afișați raportul final în format Markdown.
display(Markdown(report))
Aceasta redă raportul JobFit AI generat direct în notebook, fiind mai ușor de citit decât textul simplu.
Raportul include cea mai bună potrivire, joburi ierarhizate, scoruri de potrivire, decizii de aplicare, preocupări și un unghi de aplicare.

11. Transformați fluxul într-o aplicație web Gradio
După testarea fluxului în notebook, îl puteți transforma într-o aplicație web Gradio simplă. Creați un fișier app.py, apoi copiați codul din fișierul JobFit-AI/app.py din proiectul GitHub și lipiți-l în fișierul local.
Rulați aplicația cu:
python app.py

Apoi deschideți aplicația locală în browser la URL-ul afișat (în acest caz, http://127.0.0.1:7860/):

Aplicația Gradio oferă o interfață simplă pentru generarea de rapoarte de potrivire. Include:
- Un câmp de încărcare PDF pentru CV, unde utilizatorii își pot încărca rezumatul.
- O căsuță de text pentru preferințe de job, unde utilizatorii pot descrie tipul de roluri dorite, inclusiv tipul rolului, industria, locația, nivelul de senioritate și temele preferate.
- Un buton Generate JobFit Report pentru a porni fluxul de lucru al agentului.
- Un jurnal de progres ascuns care apare în timpul rulării și arată ce face aplicația, cum ar fi citirea CV-ului, apelarea instrumentelor și primirea ieșirilor.
- O zonă finală de raport Markdown care afișează raportul ierarhizat după ce agentul termină.
În culise, aplicația citește CV-ul încărcat, extrage textul, trimite CV-ul și preferințele către agentul JobFit AI și caută anunțuri în timp real cu Olostep. Citește până la trei pagini de job și returnează un raport Markdown structurat cu roluri ierarhizate, scoruri de potrivire, decizii de aplicare, preocupări și unghiuri de aplicare.
12. Încărcați un CV și generați un raport
Acum testați aplicația web încărcând un CV sau un PDF de rezumat și făcând clic pe Generate JobFit Report.
Pentru acest exemplu, am încărcat un CV cu aproximativ trei ani de experiență pentru a vedea dacă aplicația poate găsi joburi relevante pe baza profilului și preferințelor candidatului. Raportul a fost generat în mai puțin de un minut.
În timp ce aplicația rulează, jurnalul de progres arată fiecare pas al fluxului de lucru, inclusiv:
- citirea CV-ului
- extracția textului din fiecare pagină
- pornirea rulării agentului
- apelarea instrumentului de căutare de joburi
- returnarea ieșirii instrumentului

După finalizarea rulării, aplicația afișează raportul final în format Markdown.
Raportul începe cu cea mai bună potrivire, urmată de un tabel cu joburi ierarhizate. Apoi oferă note mai detaliate pentru fiecare rol, inclusiv scorul de potrivire, decizia de aplicare, motivele pentru care rolul se potrivește, posibile preocupări și un unghi de aplicare.

În acest exemplu, rezultatul principal a fost un rol de Senior Data Science Writer la NannyML. Deoarece rolul se potrivea cu experiența candidatului în data science, redactare tehnică și conținut AI, a părut o potrivire solidă.
Puteți face clic pe linkul Apply here din raport pentru a deschide pagina jobului și a revizui anunțul complet înainte de a decide dacă aplicați.

Notă: Dacă întâmpinați probleme la rularea proiectului local, verificați depozitul GitHub: kingabzpro/JobFit-AI. Acesta include notebook-ul, fișierul app.py și instrucțiuni de configurare pentru a vă ajuta să instalați dependențele și să rulați proiectul local.
Gânduri finale
JobFit AI folosește Kimi K2.6, Olostep și OpenAI Agent SDK pentru a rezolva două probleme comune pentru persoanele care își schimbă rolul sau aplică activ la joburi.
Prima problemă este să știi unde să aplici. Există multe job board-uri, platforme și pagini de carieră ale companiilor, dar nu este întotdeauna clar care roluri merită timpul dumneavoastră. Această aplicație ajută la restrângerea opțiunilor folosind CV-ul și preferințele candidatului pentru a găsi joburi mai relevante pentru experiența sa.
A doua problemă este filtrarea unui număr prea mare de anunțuri. În loc să verificați manual fiecare job board, agentul caută anunțuri active, citește pagini de job selectate și creează un raport structurat cu cea mai bună potrivire, joburi ierarhizate, scoruri de potrivire, preocupări și unghiuri de aplicare. Astfel este mai ușor să vă concentrați pe rolurile care chiar merită aplicarea.
API-ul Kimi K2.6 a funcționat, de asemenea, bine în acest flux bazat pe agent. A fost rapid, fiabil și eficient în a urma instrucțiuni structurate. În timpul testării, când agentului i s-au permis până la 25 de ture, acesta a căutat și a extras mai multe pagini în profunzime, dar rularea a durat aproximativ cinci minute. Pentru a echilibra calitatea și viteza, am restricționat fluxul la o singură căutare și până la trei citiri de pagini, ceea ce a ajutat la generarea raportului în mai puțin de un minut.
Puteți îmbunătăți calitatea raportului de job crescând numărul de pași permiși, rezultatele căutării sau paginile citite. De exemplu, dacă măriți limita agentului la 30 de ture și îi permiteți să citească mai multe pagini de job, poate produce un raport mai profund cu mai multe roluri și recomandări mai solide. Totuși, acest lucru va crește și timpul de rulare și utilizarea API-ului.
Dacă sunteți interesat să creați instrumente agentice similare, consultați și celelalte tutoriale noastre API pentru a construi:
Întrebări frecvente despre Kimi K2.6
Ce este Kimi K2.6?
Kimi K2.6 este cel mai nou model agentic open-weight al Moonshot AI, lansat în aprilie 2026. Este construit pe o arhitectură Mixture-of-Experts (MoE) cu ~1 trilion de parametri totali, activând 32 de miliarde per forward pass, și este optimizat pentru programare, utilizarea de instrumente și sarcini de agent pe termen lung.
Care este fereastra de context a lui Kimi K2.6?
Kimi K2.6 acceptă o fereastră de context de 262.144 tokeni (256K). Acest lucru îl face potrivit pentru a procesa coduri întregi, documente lungi sau rulări multi-step ale unui agent într-o singură sesiune.
Cât costă Kimi K2.6 prin API?
Direct prin API-ul Kimi, tokenii de intrare sunt taxați la 0,95 $/1M (cache miss) și 0,16 $/1M (cache hit), cu ieșirea la 4,00 $/1M tokeni. Furnizorii terți oferă parțial tarife mai mici, începând de la aproximativ 0,60 $/1M intrare și 2,80 $/1M ieșire.
Kimi K2.6 acceptă un mod de gândire?
Da, Kimi K2.6 acceptă atât un mod de gândire (raționare extinsă), cât și un mod instant (răspunsuri mai rapide, fără gândire). În tutorial, modul de gândire este dezactivat explicit prin extra_body={"thinking": {"type": "disabled"}} pentru a păstra ieșirile mai curate și mai rapide.
Cum se descurcă Kimi K2.6 pe benchmark-uri de programare agentică?
Kimi K2.6 obține 80,2 pe SWE-Bench Verified, fiind cel mai puternic model open-source la acel nivel, cu performanțe imediat în urma modelelor închise precum Claude Opus 4.6 (80,8%) și Gemini 3.1 Pro (80,6%). Pe BrowseComp, obține 83,2, urcând la 86,3 cu modul Agent Swarm, situându-se imediat după GPT-5.5 Pro (90,1) și previzualizarea nepublicată Claude Mythos (86,9).