Умный подбор подрядчиков (explainable contractor matching)
Сервис объяснимого подбора до трёх подрядчиков для мероприятия с тремя явными исходами, trace по каждому кандидату и LLM-объяснениями, которые…
О проекте
Команда: rassengan
Кейс HackAlem.ai: Креативные индустрии — Firebird
Стадия: Доведённый продукт
Задача кейса: «#79-lite»: подобрать до 3 подрядчиков для мероприятия и объяснить выбор
Суть
Сервис объяснимого подбора до трёх подрядчиков для мероприятия с тремя явными исходами, trace по каждому кандидату и LLM-объяснениями, которые проверяются и один раз исправляются.
Как устроено
FastAPI /match: кандидаты по городу и категории, затем жёсткие фильтры по порядку (занятость на дату → формат → бюджет → часы → язык) с подсчётом причин, аддитивный скор с разбивкой (тип события 40, категория до 20, язык, часы, цена, штрафы за синтетику и досчитанные поля), сортировка (-score, id). explain.py делает один вызов OpenAI на все три карточки. explain_check проверяет каждый текст: не больше 2 предложений, без общих фраз и чисел вне фактов, отличается от соседней карточки. Отклонённый текст получает одну попытку исправления в пределах LLM_TIMEOUT_S, иначе подставляется шаблон. Опционально /parse заполняет форму из свободного текста.
Ключевые решения
- жёсткие фильтры + аддитивный скоринг
- trace кандидатов
- LLM-проверка и self-correction
- шаблонный fallback
- разбор свободного текста в поля формы
Особенности
Цикл «сгенерировать → проверить → исправить один раз → шаблон» с жёстким валидатором фактов в тексте LLM. Командная инфраструктура для Claude Code: .claude/agents (qa-tester, rules-auditor), skills, git-хуки rules-check и акт приёмки в docs/acceptance. По README около 200 тестов.
Стек
Python 3.9+ · FastAPI · Uvicorn · Pydantic · pytest · OpenAI SDK · HTML
Модели
OpenAI gpt-5.4-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-77644574-rassengan.
README
README.mdУмный подбор подрядчиков: explainable contractor matching
Команда rassengan · HackAlem AI, 23.09.2026 · трек «Креативные индустрии» · кейс «Умный подбор подрядчиков (#79-lite)»
Что делает решение (What it does)
Заказчик мероприятия уже выбрал город и тип события и получил каталог подрядчиков. Сервис помогает выбрать из этого каталога, а не удлиняет список: по параметрам заказа он возвращает до 3 карточек подрядчиков, и у каждой есть конкретное объяснение, почему этот подрядчик здесь.
- Вход: город, дата, тип мероприятия, категория подрядчика, бюджет (₸); опционально длительность (ч) и язык.
- Выход: до 3 карточек (имя, категория, город, цена «от», объяснение в 1–2 предложения) и один из трёх явных исходов:
- подобрали N подрядчиков;
- в этом городе такой категории нет (и в каких городах она есть);
- кандидаты есть, но ни один не проходит по условиям, с разбивкой причин: заняты на дату, не тянут бюджет, не берут этот формат.
- Если подходящих меньше трёх, сервис говорит, сколько их и почему меньше.
- Занятый на выбранную дату подрядчик никогда не попадает в выдачу. Площадки ищутся так же, как люди: у них тот же календарь.
- Детерминизм: тот же запрос даёт тот же порядок карточек.
- Заказ своими словами (опционально, с ключом OpenAI): «Нужен ведущий на казахском на той 15 октября в Алматы, бюджет до 1 миллиона» → LLM заполняет поля формы (только значениями из каталога, дату и бюджет не угадывает), недостающие поля подсвечиваются, поиск запускает пользователь.
- Календарь занятости покрывает 23.09.2026–31.12.2026; даты вне диапазона отклоняются с понятным сообщением (а не объявляются «свободными»).
Полное ТЗ кейса (дословно): docs/CASE_SPEC_RU.md. Разбор условий и Definition of Done: docs/TASK.md.
Архитектура (Architecture)
браузер (web/index.html)
│ POST /parse (text) ── опционально: LLM → поля формы (проверка по /options и календарю)
│ POST /match (city, date, event_type, category, budget_kzt, hours?, language?)
▼
FastAPI (app/main.py) ── каталог загружается один раз при старте (app/data.py, CSV)
│
▼
app/matching.py: детерминированное ядро
0. дата вне 23.09–31.12.2026 → HTTP 422 с объяснением
1. кандидаты = город + категория → нет? исход «в городе нет такой категории»
2. жёсткие фильтры по порядку, с подсчётом причины отказа:
занят на дату → не берёт формат → цена выше бюджета → мало часов → нет языка
→ никто не прошёл? исход «кандидаты есть, но…»
3. аддитивный скор с разбивкой по компонентам, сортировка (-score, id)
4. топ-3 + trace по каждому кандидату (прошёл / отклонён и почему)
│
▼
app/explain.py: объяснения
├─ app/llm.py: один основной вызов OpenAI на ответ (все 3 карточки сразу) и не более одного
│ вызова на исправление; только факты карточек, причины их места в выдаче и отличающий
│ каждую карточку фрагмент её описания (разбор свободного текста — отдельный вызов /parse)
├─ app/explain_check.py: проверка каждого текста: ≤2 предложений, без общих фраз,
│ без чисел, которых нет в фактах, есть конкретный факт, не похоже на соседнюю карточку,
│ без технических терминов и ID, без «данных нет», запрошенный язык подтверждён,
│ без превосходной степени и без сравнений при равной оценке (порядок тогда — только по id)
├─ самоисправление: отклонённые тексты с причиной отказа отправляются модели на ОДНУ
│ попытку исправления, если осталось время из бюджета LLM_TIMEOUT_S; затем повторная проверка
└─ шаблон: детерминированное объяснение из фактов, если нет ключа, ошибка/таймаут или текст
не прошёл проверку и после исправления
Почему так. Порядок карточек, фильтры и исходы считаются обычным кодом, поэтому они проверяемы, повторяемы и не зависят от LLM. LLM отвечает только за то, в чём он силён: превратить факты конкретной карточки в короткое человеческое объяснение. Проверщик не пропускает выдуманные числа и рекламные фразы. Без ключа сервис работает полностью на шаблонах.
Как считается скор (app/matching.py)
| Компонент | Баллы |
|---|---|
| В описании упоминается запрошенный тип мероприятия (основы слов и синонимы) | 40 |
| Совпадение слов категории с описанием | до 20 |
| Язык: запрошенный язык поддерживается (10) · без запроса языка: 2+ языков (2) | 10 / 2 |
| Запас по часам относительно запрошенной длительности | до 5 |
| Цена относительно бюджета (дешевле = немного лучше); неизвестная цена: −2 | до 5 |
Качество данных: −1 за каждый флаг price_imputed, city_imputed, synthetic | −1…−3 |
Разбивка скора видна в карточке (блок «Расчёт оценки»), trace всех кандидатов — в блоке «Проверка всех кандидатов»; то же есть в ответе API (score_breakdown, trace).
Технологии и данные (Tech and data)
- Python 3.9+, FastAPI, Uvicorn, Pydantic, pytest. Интерфейс: одна статическая HTML-страница без сборки.
- LLM: OpenAI Chat Completions (
openaiSDK), модель задаётся черезOPENAI_MODEL. Проверено сgpt-5.4-mini. - Данные: официальный анонимизированный каталог кейса,
data/hackathon-dataset-anonymized.csv(66 профилей), и HTML-превью. Описание полей:data/README.md. Собственные профили в каталог не добавлялись. Тестовые синтетические профили лежат отдельно вtests/fixtures/.
Системные требования (System requirements)
- macOS, Linux или Windows (на Windows без
make, см. блок PowerShell ниже). - Python 3.9 или новее (Python 3.8 не подходит),
make(для macOS/Linux), доступ к PyPI для установки зависимостей. - Около 200 МБ диска для виртуального окружения. GPU не нужен.
- Для объяснений от LLM нужен интернет, ключ OpenAI и имя модели (
OPENAI_API_KEY+OPENAI_MODEL). Без них всё работает на шаблонах.
Зависимости (Dependencies)
Закреплены в requirements.txt: fastapi, uvicorn, pydantic, python-dotenv, openai, pytest, httpx. make setup ставит их в локальное окружение .venv, а не в системный Python.
Установка и запуск (Install and run)
git clone https://github.com/BAITC-Hacks/hack-77644574-rassengan.git
cd hack-77644574-rassengan
make setup # создаёт .venv и ставит зависимости
cp .env.example .env # необязательно: ключ OpenAI для LLM-объяснений (см. «Конфигурация»)
make run # http://localhost:8000
Откройте http://localhost:8000 в браузере.
Без make (Linux/macOS):
python3 --version # нужен 3.9 или новее
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python -m uvicorn app.main:app --port 8000
Windows (PowerShell). Нужен Python 3.9 или новее; на некоторых машинах команда python указывает на старый Python 3.8. Сначала найдите подходящий Python:
py --list # список установленных версий (если есть лаунчер py)
python --version # версия команды python
Выберите один вариант и выполните его команды:
# Вариант A: есть лаунчер py и в списке есть 3.9+ (например 3.12)
py -3.12 -m venv .venv
# Вариант B: python --version показывает 3.9 или новее
python -m venv .venv
# Вариант C: ни то ни другое — укажите полный путь к python.exe нужной версии, например:
& "$env:LOCALAPPDATA\Programs\Python\Python312\python.exe" -m venv .venv
Дальше одинаково для всех вариантов:
.venv\Scripts\python --version # проверьте: 3.9 или новее
.venv\Scripts\python -m pip install -r requirements.txt
.venv\Scripts\python -m uvicorn app.main:app --port 8000
Если Python 3.9+ не установлен: установите Python 3.12 с python.org (галочка «Add python.exe to PATH»).
Тесты на Windows: .venv\Scripts\python -m pytest -q.
Доступ для проверяющих: личные аккаунты не нужны (Access for judges)
Регистрации и логина нет. Без ключа OpenAI сервис полностью работоспособен: все фильтры, ранжирование, исходы и объяснения работают, объяснения строятся детерминированным шаблоном из фактов карточки (на карточке пометка «шаблон»). Чтобы увидеть LLM-объяснения (пометка «AI-объяснение»), нужно заполнить в .env обе переменные: OPENAI_API_KEY и OPENAI_MODEL (например, gpt-5.4-mini). Если заполнена только одна, используются шаблоны.
Конфигурация: переменные окружения (Configuration, environment variables)
| Переменная | Назначение | Пример |
|---|---|---|
OPENAI_API_KEY | Ключ OpenAI для LLM-объяснений. Пусто: шаблонные объяснения | sk-... |
OPENAI_MODEL | Модель OpenAI. Пусто: шаблонные объяснения | gpt-5.4-mini |
LLM_TIMEOUT_S | Таймаут вызова LLM в секундах; при превышении используется шаблон | 8 |
DATA_PATH | Необязательно: путь к каталогу (CSV или JSONL) | data/hackathon-dataset-anonymized.csv |
Проверка основного сценария (Verify the main scenario)
Запустите make run, откройте http://localhost:8000 и выполните запросы ниже. Можно также через API:
curl -s -X POST localhost:8000/match -H 'Content-Type: application/json' \
-d '{"city":"Алматы","date":"2026-10-15","event_type":"свадьба","category":"Ведущий","budget_kzt":1000000}'
| # | Запрос | Ожидаемый результат |
|---|---|---|
| 1 | Плотная категория: Алматы · 15.10.2026 · свадьба · Ведущий · 1 000 000 ₸ | «Подобрали 3 подрядчиков»: Кики, Эмилия, Сон Гоку. У каждой карточки своё объяснение |
| 2 | Та же, другая дата: то же, но 16.10.2026 | Другая выдача: Хаул, Мицури Канроджи. В блоке «Проверка всех кандидатов» у Кики, Эмилии и Сон Гоку: «занят на 16.10.2026» |
| 3 | Редкая категория: Алматы · 15.10.2026 · свадьба · Флорист · 500 000 ₸ | 2 карточки и объяснение, почему меньше трёх: в городе всего 2 флориста |
| 4 | Нет категории в городе: Астана · 15.10.2026 · свадьба · Декоратор · 1 000 000 ₸ | «В городе Астана нет подрядчиков категории Декоратор. Эта категория есть в городах: Алматы.» |
| 5 | Кандидаты есть, никто не проходит: Алматы · 15.10.2026 · свадьба · Декоратор · 1 000 000 ₸ | «Кандидаты есть (3), но ни один не проходит по условиям: 3 с ценой выше бюджета.» |
Повторите любой запрос: порядок карточек тот же (детерминизм). Ответ приходит за несколько секунд с LLM и мгновенно на шаблонах.
Режим «своими словами» (нужны OPENAI_API_KEY и OPENAI_MODEL): нажмите «Пример» → «Разобрать» → поля формы заполнятся (Алматы · 15.10.2026 · той · Ведущий · 1 000 000 · казахский) → «Подобрать». Ручной подбор через форму работает без ключа; текстовый разбор требует и OPENAI_API_KEY, и OPENAI_MODEL. Без них «Разобрать» отвечает: «Разбор текста доступен только с ключом OpenAI и моделью (OPENAI_API_KEY, OPENAI_MODEL); заполните форму». Если ключ задан, но AI не ответил вовремя или вернул некорректный ответ: «Не удалось разобрать текст…; заполните форму вручную».
Границы календаря: дата 22.09.2026 или 01.01.2027 → сообщение «Календарь занятости покрывает только 23.09.2026–31.12.2026; выберите дату в этом диапазоне.» (API: HTTP 422).
Автоматическая проверка сценариев и замер качества (make demo, make eval)
make demo # без ключа: все 5 сценариев README, границы календаря, детерминизм, правила объяснений, скорость — таблица ✅/❌
make eval # с ключом и моделью: 24 фиксированных запроса ×2, отчёт в docs/EVAL.md
Windows: .venv\Scripts\python scripts\demo.py и .venv\Scripts\python scripts\eval.py.
Замеры на 23.09.2026 (docs/EVAL.md — прогон на финальной версии 4c256b9, gpt-5.4-mini, 24 запроса ×2): проверщик принял AI-объяснения для 22 из 23 карточек (19 с первой попытки, 3 после самоисправления), 1 — честный откат на шаблон с указанием причины; среднее время ответа около 1 с, максимум около 4 с; порядок карточек при повторе совпал в 24 из 24 запросов; ошибок вызовов 0. В более ранних прогонах доля принятых с первой попытки составляла 87–100%. Это результат фиксированной выборки, а не гарантия для всех запросов; формулировки модели между прогонами различаются.
Независимая проверка участника Nurdaulet на Windows (нашла и дефект различимости шаблонов, исправлен; docs/acceptance/LIVE_EVAL_2a45fc7.md, docs/ACCEPTANCE_REVIEW.md): чистый clone и установка по README, 202 теста, make demo 28/28; в живом прогоне 20/23 AI-объяснений приняты сразу и 3/23 — после самоисправления, шаблон 0/23; порядок совпал 24/24.
Тесты (Tests)
make test
210 офлайн-тестов (реальные вызовы API в тестах заблокированы, см. tests/conftest.py):
tests/test_dod.py: Definition of Done кейса на реальном каталоге: детерминизм, разная выдача на двух датах из-за занятости, плотная/редкая/пустая категория, словесное объяснение пустого результата, скорость;tests/test_matching.py: фильтры, причины отказа, три исхода, «почему меньше трёх»;tests/test_explain.py: LLM-объяснения через заглушку: принятие хорошего ответа; откат на шаблон при общих фразах, выдуманных числах, похожих текстах, ошибке или таймауте;tests/test_parse.py: разбор текста через заглушку: значения только из каталога, дата вне календаря, пустой текст, работа без ключа;tests/test_api.py,tests/test_dataset.py: API, границы календаря и загрузка каталога;tests/test_distinct.py: объяснения одного ответа различаются без имён (регрессия из приёмки: две группы с одинаковым началом описания) и на сетке 1344 запросов;tests/test_demo_script.py:make demoпроходит без ошибок, в том числе в консоли Windows с кодировкой CP1251.
Использование AI-инструментов (AI tools used)
Разработка велась с AI-агентами. Все изменения проверены командой и зафиксированы в истории коммитов под аккаунтами участников.
- OpenAI Codex (CLI): основной исполнитель кода: каркас, фильтры и ранжирование, trace, LLM-объяснитель с проверкой, разбор текста, календарные границы, тесты. Коммиты помечены «built with Codex». Codex также использовался Nurdaulet для независимой приёмки (
docs/ACCEPTANCE_REVIEW.md). - Claude Code: планирование, разбор ТЗ, ревью изменений, проверка на реальных данных, README.
- Claude Design: визуальное оформление страницы
web/index.html(вёрстка и стили; логика и запросы к API не менялись, проверено тестами и прогоном в браузере). - В самом продукте: OpenAI (
OPENAI_MODEL) пишет объяснения карточек только из переданных фактов, с проверкой и детерминированным откатом.
Заимствованный код и источники (Prior code and sources)
- Подготовленный набор (kit): добавлен в день соревнования, только настройка, без кода проекта: инструкции для агентов, навыки, шаблоны, скрипты проверки правил. Полный список и назначение в
KIT.md:AGENTS.md,CLAUDE.md,docs/HACKATHON_RULES.md,docs/RUBRIC.md,docs/TASK.md,docs/PLAN.md,docs/WORKFLOW.md,docs/COMMANDS.md,.claude/*,.vscode/*,scripts/rules-check.sh,scripts/install-hooks.sh,scripts/push-advice.sh,scripts/hooks/*,scripts/smoke.py,.hackathon-rules.conf, шаблоныREADME.md,.env.example,.gitignore,Makefile. - Данные: официальный каталог кейса (
data/), предоставлен организаторами для хакатона. - Библиотеки (открытый код, см.
requirements.txt): FastAPI (MIT), Uvicorn (BSD-3), Pydantic (MIT), python-dotenv (BSD-3), openai-python (Apache-2.0), pytest (MIT), HTTPX (BSD-3). - Весь код в
app/,web/,tests/, а такжеscripts/demo.pyиscripts/eval.pyнаписан во время соревнования 23.09.2026 после 13:00.
Команда (Team)
- Askhat (GitHub: askmirkhanov-boop): тимлид и основной разработчик: архитектура, ядро подбора, LLM-объяснения и их проверка, интеграция AI-агентов.
- Nurdaulet (GitHub: Nurdauletuj): проверка качества и приёмка: независимое ревью требований и кода, воспроизводимые демо-сценарии, проверка календарных границ, бизнес-гипотеза (
docs/ACCEPTANCE_REVIEW.md), подготовка защиты.
Развитие (Roadmap)
Планы, а не реализованные функции:
- Смысловое сопоставление на большом каталоге: эмбеддинги описаний вместо основ слов и синонимов; фильтры остаются детерминированными, меняется только компонент релевантности.
- Живой календарь: синхронизация занятости с календарями подрядчиков вместо статического окна 23.09–31.12.2026.
- Обратная связь: учитывать, кого заказчики в итоге выбирают, для настройки весов ранжирования (с сохранением объяснимой разбивки баллов).
- Другие каталоги: площадки, кейтеринг, аренда оборудования; конвейер «фильтры → скор → объяснение → проверка» не зависит от предметной области.
- B2B API для агрегаторов и ивент-агентств:
/matchи/parseкак встраиваемый модуль подбора. Спрос и модель оплаты (подписка или оплата за использование) — гипотеза, не проверенная на пользователях.
Известные ограничения (Known limitations)
- LLM-объяснения требуют ключ OpenAI и интернет. Без них используются шаблонные объяснения из фактов каталога; они звучат суше. Различимость шаблонов проверена тестом на сетке из 1344 запросов по всем сочетаниям город × категория × формат (4 даты × 3 бюджета): совпадающих объяснений 0; это ограниченная сетка, а не доказательство для любых входных данных.
- Проверка LLM-текстов лексическая (числа, запрещённые фразы, похожесть), а не полная семантическая. Сомнительный текст заменяется шаблоном.
- Совпадение «по смыслу описания» определяется по основам слов и синонимам типа мероприятия, без эмбеддингов.
- Каталог маленький (66 профилей; в Астане 15). Для многих сочетаний честный ответ: «меньше трёх» или «никто не подходит».
- Прототип рассчитан на проверку одним пользователем: кэш объяснений защищён общей блокировкой на время вызова LLM, поэтому одновременные запросы с AI обрабатываются последовательно; параллельная нагрузка не тестировалась.
- Бронирование, заявки и уведомления подрядчикам не входят в задачу (по ТЗ).
- Цена «от» не равна итоговой смете; календарь занятости покрывает только 23.09–31.12.2026 и требует регулярного обновления.
- Каталог анонимизирован и частично синтетический: он подтверждает работу прототипа, но не рыночный спрос. Бизнес-гипотеза (B2B-модуль для агрегаторов и ивент-агентств) не проверена на реальных пользователях.
Авторы коммитов
История коммитов
- 2026-09-23 17:20docs: record final acceptance and regression evidenceNurdauletuj
- 2026-09-23 17:08docs: final live quality report on 4c256b9, final numbers in README, hourly log completeAskhat
- 2026-09-23 17:03fix: distinct facts only from the requested event, late LLM answers fall back to template, «более N» allowed on tied scoresAskhat
- 2026-09-23 17:00fix: no unsupported comparisons in AI explanations (equal scores claim no advantage, no superlatives)Askhat
- 2026-09-23 16:49fix: explanations of one response always differ (DoD2): distinct clause from the full description, duplicate-template guardAskhat
- 2026-09-23 16:40docs: architecture shows self-correction loop, accurate scripts disclosure, 202 tests, link to independent Windows and live-AI verification; TASK deliverables closedAskhat
- 2026-09-23 16:38docs: verify Windows and live AI, review redesign and update pitchNurdauletuj
- 2026-09-23 16:31fix: make demo works on Windows CP1251 consoles (plain [OK]/[FAIL] marks when emoji cannot be encoded)Askhat
Все коммиты (28)
- 2026-09-23 16:27feat: redesigned page (Claude Design): two-step panel, outcome banners, ranked cards, loading states, narrow-screen layoutAskhat
- 2026-09-23 16:09docs: live quality report (docs/EVAL.md) on 66d5e6d and honest range from two runs in READMEAskhat
- 2026-09-23 16:07feat: make demo (all README scenarios, calendar, determinism, explanation rules, speed without a key) and make eval (live quality measurement) (built with Codex)Askhat
- 2026-09-23 16:07fix: honest /parse error when AI fails with a configured key; README covers free-text mode, Windows Python selection, 186 testsAskhat
- 2026-09-23 15:47feat: self-correcting explanations: generate, verify, revise once within the time budget (built with Codex)Askhat
- 2026-09-23 15:41docs: record approved acceptance checks for 5b44e64 and 9f06fc8Nurdauletuj
- 2026-09-23 15:25fix: explanations without internal terms or unrequested-field filler, exactly two sentences, no self-introduction quotes (built with Codex)Askhat
- 2026-09-23 15:20feat: ranking reasons in explanations, requested language confirmed, absence filler rejected, example button (built with Codex)Askhat
- 2026-09-23 15:16docs: verify offline demo and prepare defense pitchNurdauletuj
- 2026-09-23 15:13feat: free-text request parsing into validated form fields, single empty-result message (built with Codex)Askhat
- 2026-09-23 15:02docs: Windows PowerShell setup with Python version check, both OpenAI vars explained, test count updatedAskhat
- 2026-09-23 15:00fix: reject dates outside the 23.09-31.12.2026 calendar window, complete README team and limitations (built with Codex)Askhat
- 2026-09-23 14:45feat: grounded LLM prompt without shared boilerplate, date- and id-safe checker, full README, venv setup (built with Codex)Askhat
- 2026-09-23 14:38chore: merge teammate changesNurdauletuj
- 2026-09-23 14:32docs: add acceptance review and demo scenarios with CodexNurdauletuj
- 2026-09-23 14:21feat: LLM explainer with validation and fallback, distinct template explanations (built with Codex)Askhat
- 2026-09-23 14:00feat: explainable ranking, candidate trace, clear outcome messages, DoD tests (built with Codex)Askhat
- 2026-09-23 13:29feat: contractor matching scaffold with filters, ranking, 3 outcomes and tests (built with Codex)Askhat
- 2026-09-23 13:24docs: choose contractor-matching case, add task spec, rubric, plan and official datasetAskhat
- 2026-09-23 13:03chore: add prepared kit (see KIT.md)Askhat
Структура репозитория (67 файлов)
.claude/agents/qa-tester.md .claude/agents/rules-auditor.md .claude/settings.json .claude/skills/ask-codex/SKILL.md .claude/skills/checkpoint/SKILL.md .claude/skills/clean-clone-check/SKILL.md .claude/skills/readme-writer/SKILL.md .claude/skills/review-diff/SKILL.md .claude/skills/rubric-check/SKILL.md .claude/skills/task-intake/SKILL.md .env.example .gitignore .hackathon-rules.conf AGENTS.md CLAUDE.md KIT.md Makefile README.md app/__init__.py app/data.py app/explain.py app/explain_check.py app/llm.py app/main.py app/matching.py app/snippets.py data/README.md data/hackathon-dataset-anonymized.csv data/hackathon-dataset-preview.html docs/ACCEPTANCE_REVIEW.md docs/CASE_SPEC_RU.md docs/COMMANDS.md docs/EVAL.md docs/HACKATHON_RULES.md docs/PITCH.md docs/PLAN.md docs/RUBRIC.md docs/TASK.md docs/WORKFLOW.md docs/acceptance/JUDGE_PROBE_5bb978f.json docs/acceptance/JUDGE_PROBE_cd242e9.json docs/acceptance/JUDGE_PROBE_d7f3ff6.json docs/acceptance/LIVE_BANDS_d7f3ff6.json docs/acceptance/LIVE_EVAL_2a45fc7.json docs/acceptance/LIVE_EVAL_2a45fc7.md docs/acceptance/LIVE_TIED_cd242e9.json docs/acceptance/README.md requirements.txt scripts/demo.py scripts/eval.py scripts/hooks/pre-commit scripts/hooks/pre-push scripts/install-hooks.sh scripts/push-advice.sh scripts/rules-check.sh scripts/smoke.py tests/conftest.py tests/fixtures/profiles_sample.csv tests/test_api.py tests/test_dataset.py tests/test_demo_script.py tests/test_distinct.py tests/test_dod.py tests/test_explain.py tests/test_matching.py tests/test_parse.py web/index.html
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.