Course
Kimi K2.6 — новейшая открытая модель Moonshot AI, созданная для программирования, длительных цепочек действий, работы с инструментами и агентных сценариев. Модель доступна через Kimi.com, приложение Kimi, Kimi Code и API, что делает её полезной для практических ИИ‑приложений, которым нужны рассуждение, вызов инструментов и структурированные ответы.
В этом руководстве вы создадите JobFit AI — ИИ‑ассистента по поиску работы, который читает резюме кандидата, ищет актуальные вакансии, проверяет выбранные страницы и формирует ранжированный отчёт о соответствии. Kimi K2.6 хорошо подходит для этого проекта, поскольку поддерживает сценарии с длинным контекстом, вызовы инструментов, а также режимы с размышлением и без него через платформу Kimi API.
В проекте используются:
- Kimi K2.6 как модель рассуждения
- Olostep для живого веб‑поиска и парсинга страниц вакансий
- pypdf для извлечения текста из резюме кандидата
- OpenAI Agents SDK для создания агента с инструментами
- Gradio для превращения пайплайна в простое веб‑приложение
К концу руководства у вас будет рабочее приложение, в котором пользователи смогут загрузить резюме, описать предпочтения и получить ранжированный список релевантных вакансий меньше чем за минуту.
Если вы только начинаете работать с агентным ИИ, настоятельно рекомендую пройти наш скилл‑трек AI Agents Fundamentals. В нём освещаются основы шаблонов проектирования, MCP и мультиагентные системы.
Необходимые условия
Перед началом убедитесь, что у вас есть:
- Python 3.11+
- Ключ API Kimi
- Как минимум $5 на балансе аккаунта Moonshot AI
- Ключ API Olostep
- Резюме в формате PDF
- Базовые знания Python
1. Настройте окружение Python
Создайте новую папку проекта:
mkdir JobFit-AI
cd JobFit-AI
Затем установите необходимые пакеты:
pip install gradio openai pypdf openai-agents
Основные пакеты:
-
gradio: создаёт веб‑интерфейс -
openai: подключается к API, совместимым с OpenAI -
pypdf: извлекает текст из PDF‑файлов -
openai-agents: создаёт ИИ‑агента, использующего инструменты
Далее создайте аккаунты и сгенерируйте ключи API:
- Создайте бесплатный аккаунт Olostep и получите ключ API в консоли Olostep. Также можно оформить Starter‑тариф за $9/мес., включающий 5 000 запросов. Этого достаточно, чтобы протестировать и развернуть приложение.
- Перейдите на платформу Kimi, пополните баланс минимум на $5 и сгенерируйте ключ API.
Задайте ключи API Kimi и Olostep как переменные окружения. MOONSHOT_API_KEY используется для доступа к API Kimi K2.6, а OLOSTEP_API_KEY — для поиска и парсинга актуальных страниц с вакансиями.
2. Определите конфигурацию проекта
Запустите Jupyter Notebook, создайте новую ячейку и добавьте необходимые импорты и настройки проекта.
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
Теперь задайте имя модели, конечные точки API, максимальное число ходов агента, путь к резюме и предпочтения по вакансиям.
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)
Значения KIMI_MODEL и KIMI_BASE_URL указывают приложению использовать Kimi K2.6 через OpenAI‑совместимый endpoint Moonshot AI. URL‑адреса Olostep применяются для живого поиска вакансий и парсинга страниц.
Переменная cv_path указывает на PDF‑файл резюме кандидата. Убедитесь, что PDF сохранён в той же папке проекта, или обновите путь, если файл хранится в другом месте.
Переменная preferences сообщает агенту, какие вакансии нужно искать. Вы можете изменить её в зависимости от целевой роли, отрасли, локации, уровня и предпочитаемого формата работы.
Мы отключаем трейсинг с помощью set_tracing_disabled(True), поскольку трейсинг в OpenAI Agents SDK включён по умолчанию. Так как в этом проекте Kimi используется через OpenAI‑совместимый endpoint, отключение трейсинга упрощает локальную настройку и предотвращает проблемы, связанные с трейсингом у стороннего провайдера модели.
3. Подключитесь к API Kimi K2.6
Далее настройте клиент Kimi, используя сохранённый ранее ключ API в переменной окружения.
kimi_client = AsyncOpenAI(
api_key=os.environ["MOONSHOT_API_KEY"],
base_url=KIMI_BASE_URL,
)
Это создаёт клиент API для Kimi. api_key загружается из MOONSHOT_API_KEY, а base_url указывает на OpenAI‑совместимый endpoint Moonshot AI.
Затем оберните модель Kimi, чтобы её можно было использовать внутри OpenAI Agents SDK:
kimi_model = OpenAIChatCompletionsModel(
model=KIMI_MODEL,
openai_client=kimi_client,
)
Теперь задайте настройки модели:
model_settings = ModelSettings(
tool_choice="auto",
parallel_tool_calls=True,
extra_body={"thinking": {"type": "disabled"}},
)
Параметр tool_choice="auto" позволяет агенту самому решать, когда вызывать инструменты. parallel_tool_calls=True даёт возможность при необходимости выполнять несколько вызовов инструментов параллельно.
Мы также отключаем режим размышления Kimi с помощью extra_body={"thinking": {"type": "disabled"}}. Это делает вывод чище и лучше подходит для структурированного отчёта о соответствии.
Наконец, создайте конфигурацию запуска:
run_config = RunConfig(
workflow_name="JobFit AI Kimi Search",
tracing_disabled=True,
)
Параметр workflow_name задаёт понятную метку для этого запуска. Мы также оставляем трейсинг отключённым, поскольку в проекте используется Kimi через OpenAI‑совместимый endpoint, а не бэкенд трейсинга OpenAI.
4. Извлеките текст из резюме кандидата
Теперь используйте PdfReader, чтобы загрузить резюме кандидата и извлечь текст с каждой страницы.
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}")
Этот код читает PDF‑файл, указанный в cv_path, извлекает текст с каждой страницы и объединяет его в одну строку.
Ограничение [:12000] оставляет текст резюме достаточно коротким, чтобы он комфортно поместился в подсказку для агента, при этом давая модели достаточно контекста об опыте, навыках и предпочтениях кандидата.
Вывод будет примерно таким (зависит от имени и длины вашего файла резюме):
Loaded 2,946 characters from abid-resume.pdf
Это подтверждает успешную загрузку резюме и показывает, сколько символов было извлечено из PDF.
5. Создайте инструкции для агента
Далее задайте инструкции, управляющие тем, как агент ищет, использует инструменты и форматирует итоговый отчёт.
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()
Эти инструкции удерживают агента в фокусе. Они ограничивают процесс одним поисковым запросом, максимум тремя чтениями страниц вакансий и фиксированной структурой отчёта в Markdown.
Правила отчёта также делают вывод удобнее для просмотра: требуются короткие пункты, кликабельные ссылки, оценки соответствия и чёткое решение по отклику на каждую роль.
6. Сформируйте рантайм‑подсказку
После определения инструкций создайте шаблон подсказки, который будет передан агенту при каждом запуске.
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()
Эта подсказка объединяет текст резюме кандидата и его предпочтения по вакансиям во время выполнения.
Заполнитель cv_text подставляется извлечённым содержимым резюме, а preferences — ранее заданными предпочтениями. Вместе они дают агенту достаточно контекста, чтобы найти релевантные вакансии и ранжировать их по соответствию.
7. Добавьте живой веб‑поиск с Olostep
Теперь, когда инструкции агента и рантайм‑подсказка готовы, добавьте два инструмента, позволяющих агенту искать в интернете и читать страницы вакансий с помощью Olostep.
Первый инструмент ищет вакансии в сети и возвращает компактный список результатов.
@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)
Декоратор @function_tool делает эту функцию Python доступной агенту как вызываемый инструмент.
Когда агенту нужны вакансии, он вызывает search_jobs с поисковым запросом. Функция отправляет запрос на endpoint поиска Olostep, собирает top‑результаты и возвращает их в формате JSON.
Каждый результат включает:
- название вакансии
- URL вакансии
- краткое описание
Второй инструмент позволяет агенту открыть и прочитать конкретную страницу вакансии.
@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]
Эта функция отправляет URL вакансии на endpoint парсинга Olostep и возвращает содержимое страницы в формате Markdown.
Ограничение [:8000] оставляет страницу достаточно короткой для обработки агентом, при этом сохраняя ключевые детали — обязанности, требования и информацию о компании.
8. Создайте агента JobFit AI
Теперь создайте агента и свяжите все ранее определённые компоненты: модель Kimi, её настройки, инструменты Olostep и инструкции агента.
agent = Agent(
name="JobFit AI",
model=kimi_model,
model_settings=model_settings,
tools=[search_jobs, read_job_page],
instructions=AGENT_INSTRUCTIONS,
)
Объект Agent — главный контроллер этого сценария.
Он использует:
kimi_modelкак модель рассужденияmodel_settingsдля управления использованием инструментов и поведением выводаsearch_jobsдля поиска актуальных вакансийread_job_pageдля парсинга выбранных страницAGENT_INSTRUCTIONSдля точного соблюдения правил поиска и отчёта
На этом этапе агент готов искать вакансии, сравнивать их с резюме кандидата и генерировать структурированный отчёт JobFit AI.
9. Запустите рабочий процесс агента
Теперь запустите агента JobFit AI, используя извлечённый текст резюме и заданные предпочтения по вакансиям.
Сначала сформируйте рантайм‑подсказку:
prompt = RUN_PROMPT_TEMPLATE.format(cv_text=cv_text, preferences=preferences)
Это подставляет в шаблон подсказки резюме кандидата и его целевые предпочтения.
Затем запустите потоковый прогон агента:
print("Starting agent run")
result = Runner.run_streamed(
agent,
prompt,
max_turns=MAX_AGENT_TURNS,
run_config=run_config,
)
Метод Runner.run_streamed() запускает рабочий процесс агента и транслирует события по мере их появления. Так проще видеть, когда агент вызывает инструмент, получает его результат и формирует итоговое сообщение.
Теперь добавьте цикл обработки стрима:
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")
Этот цикл печатает полезные обновления прогресса во время работы агента. Например, видно, когда агент ищет вакансии, читает страницу или завершает генерацию отчёта.
Наконец, сохраните итоговый вывод в переменную 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")
Переменная report хранит итоговый отчёт JobFit AI, который можно отобразить, сохранить или использовать в приложении на Gradio.
Вывод будет выглядеть примерно так:
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
Это подтверждает, что агент выполнил поиск, прочитал выбранные страницы и успешно сгенерировал итоговый отчёт.
10. Отобразите сгенерированный отчёт JobFit
После завершения прогона агента отобразите итоговый отчёт в формате Markdown.
display(Markdown(report))
Это отрендерит сгенерированный отчёт JobFit AI прямо в ноутбуке — так его легче читать, чем обычный текст.
Отчёт включает лучшую вакансию, ранжированный список, оценки соответствия, решения по отклику, возможные риски и рекомендации по подаче.

11. Превратите пайплайн в веб‑приложение Gradio
Протестировав пайплайн в ноутбуке, вы можете превратить его в простое веб‑приложение на Gradio. Создайте файл app.py, затем скопируйте код из файла JobFit-AI/app.py в проекте на GitHub и вставьте его в ваш локальный файл.
Запустите приложение командой:
python app.py

Затем откройте локальное приложение в браузере по указанному адресу (в данном случае http://127.0.0.1:7860/):

Приложение Gradio предоставляет простой интерфейс для генерации отчётов о соответствии. В нём есть:
- Поле загрузки PDF‑резюме, где пользователи загружают своё резюме.
- Текстовое поле предпочтений, где можно описать желаемые роли: тип, отрасль, локацию, уровень, тематику.
- Кнопка Generate JobFit Report для запуска рабочего процесса агента.
- Скрытый журнал прогресса, который появляется во время выполнения и показывает действия приложения, такие как чтение резюме, вызовы инструментов и получение результатов.
- Итоговая область Markdown, где отображается ранжированный отчёт после завершения работы агента.
Под капотом приложение читает загруженное резюме, извлекает текст, передаёт резюме и предпочтения агенту JobFit AI и выполняет поиск актуальных вакансий с Olostep. Оно читает до трёх страниц вакансий и возвращает структурированный отчёт в Markdown с ранжированными ролями, оценками соответствия, решениями по отклику, рисками и рекомендациями по подаче.
12. Загрузите резюме и сформируйте отчёт
Протестируйте веб‑приложение: загрузите резюме в PDF и нажмите Generate JobFit Report.
В этом примере я загрузил резюме с примерно трёхлетним опытом, чтобы проверить, сможет ли приложение найти релевантные вакансии с учётом профиля и предпочтений кандидата. Отчёт был сгенерирован меньше чем за минуту.
Во время работы приложения журнал прогресса показывает каждый шаг пайплайна, включая:
- чтение резюме
- извлечение текста с каждой страницы
- запуск прогона агента
- вызов инструмента поиска вакансий
- получение результата инструмента

После завершения прогона приложение отображает итоговый отчёт в формате Markdown.
Отчёт начинается с лучшего совпадения, затем идёт таблица ранжированных вакансий. Далее следуют подробные заметки по каждой роли: оценка соответствия, решение по отклику, причины соответствия, возможные риски и рекомендация по подаче.

В этом примере лучшим результатом стала вакансия Senior Data Science Writer в NannyML. Поскольку роль соответствует опыту кандидата в data science, техническом писательстве и ИИ‑контенте, это выглядело сильным попаданием.
Вы можете нажать ссылку Apply here в отчёте, чтобы открыть страницу вакансии и изучить объявление целиком, прежде чем решать, откликаться ли.

Примечание: если у вас возникнут проблемы с локальным запуском проекта, загляните в репозиторий GitHub: kingabzpro/JobFit-AI. В нём есть ноутбук, файл app.py и инструкции по установке зависимостей и локальному запуску проекта.
Заключение
JobFit AI использует Kimi K2.6, Olostep и OpenAI Agent SDK, чтобы решить две распространённые проблемы у людей, которые меняют роль или активно подают отклики.
Первая проблема — понять, куда подавать. Есть множество джоб‑бордов, платформ и карьерных страниц компаний, но не всегда ясно, какие роли стоят вашего времени. Это приложение помогает сузить круг, используя резюме и предпочтения кандидата, чтобы находить более релевантные его опыту вакансии.
Вторая — необходимость отфильтровать слишком много объявлений. Вместо ручной проверки каждого сайта агент ищет живые вакансии, читает выбранные страницы и формирует структурированный отчёт с лучшим совпадением, ранжированными ролями, оценками соответствия, рисками и углами подачи. Так легче сфокусироваться на ролях, на которые действительно стоит откликаться.
API Kimi K2.6 также показал себя хорошо в этом агентном сценарии: он быстрый, надёжный и эффективно следует структурированным инструкциям. В ходе тестов, когда агенту позволялось до 25 ходов, он выполнял более глубокий поиск и парсинг нескольких страниц, но на это уходило около пяти минут. Чтобы сбалансировать качество и скорость, я ограничил процесс одним поиском и максимум тремя чтениями страниц — так отчёт формируется меньше чем за минуту.
Вы можете повысить качество отчёта, увеличив число разрешённых шагов, результатов поиска или читаемых страниц. Например, если поднять лимит агента до 30 ходов и позволить читать больше страниц, отчёт получится глубже, с большим числом ролей и более сильными рекомендациями. Однако это увеличит время выполнения и расход API.
Если вы заинтересованы в создании похожих агентных инструментов, посмотрите и другие наши API‑руководства по созданию:
Частые вопросы по Kimi K2.6
Что такое Kimi K2.6?
Kimi K2.6 — последняя открыто-весовая агентная модель Moonshot AI, выпущенная в апреле 2026 года. Построена на архитектуре Mixture‑of‑Experts (MoE) с ~1 трлн общих параметров и активацией 32 млрд на проход; оптимизирована для программирования, работы с инструментами и длительных агентных задач.
Какое контекстное окно у Kimi K2.6?
Kimi K2.6 поддерживает контекстное окно 262 144 токена (256K). Это делает её подходящей для обработки целых кодовых баз, длинных документов или многошаговых прогонов агента в одной сессии.
Сколько стоит Kimi K2.6 через API?
При прямом доступе через Kimi API входные токены стоят $0.95 за 1M (при промахе кэша) и $0.16 за 1M (при попадании), выходные — $4.00 за 1M токенов. У сторонних провайдеров частично доступные более низкие ставки начинаются примерно с $0.60 за 1M входа и $2.80 за 1M выхода.
Поддерживает ли Kimi K2.6 режим размышления?
Да, Kimi K2.6 поддерживает режим размышления (углублённое рассуждение) и мгновенный режим (быстрые ответы без размышления). В руководстве режим размышления явно отключён через extra_body={"thinking": {"type": "disabled"}}, чтобы сделать ответы чище и быстрее.
Как Kimi K2.6 показывает себя на агентных бенчмарках по коду?
Kimi K2.6 набирает 80.2 на SWE‑Bench Verified, что делает её сильнейшей среди open‑source моделей на этом уровне, с результатом чуть ниже закрытых моделей вроде Claude Opus 4.6 (80.8%) и Gemini 3.1 Pro (80.6%). В BrowseComp её результат — 83.2, повышается до 86.3 в режиме Agent Swarm, что чуть ниже GPT‑5.5 Pro (90.1) и неопубликованного Claude Mythos Preview (86.9).