Демо: pantry.klimnyk.dev · увійти своїм акаунтом «Сільпо»
Відео-пітч: youtu.be/MaYrDeVMxeA
Презентація: pantry-deck.mykhailo-klimnyk.workers.dev
Знає, що вдома. Замовить, що треба. Агент, який рахує стан дому з чеків «Сільпо», збирає кошик під потребу і доводить його до дверей: заміни погоджені наперед, слот і філія з адреси, сума в межі, яку назвав гість.
Створено для хакатону «Сільпо» AI Factory.
Замовлення продуктів на тиждень у родині займає близько двадцяти хвилин, і ці хвилини йдуть не на вибір, а на пригадування: гортати старі чеки, шукати в сімейному чаті, що просили купити, і все одно забути щось, бо в момент замовлення ти не вдома і не бачиш, що закінчилось.
«Сільпо» знає, що гість купує. Ніхто не знає, що в нього вдома і коли воно закінчиться. ПанTry рахує саме це і робить з нього кошик.
Друга половина проблеми починається після кнопки «Оформити». Товару на полиці не виявилось, і збирач телефонує: посеред наради, за кермом, у ліфті. Не додзвонився, позицію знімають, і вечеря лишається без одного інгредієнта. ПанTry домовляється про заміну заздалегідь, поки гість ще за екраном: дзвінок стає непотрібним, а товар доїжджає частіше, бо замість «немає» приходить те, на що гість уже погодився.
Для кого: гість «Сільпо» з історією покупок, який замовляє додому регулярно. Найбільше виграє той, хто замовляє на родину і чиї покупки повторюються.
- Знає, що вдома. Комора будується з чеків, офлайн і онлайн разом. На кожен вид, який гість бере регулярно, рахується цикл, залишок і дата, коли воно закінчиться. Свіже важить більше за торішнє. Там, де ритму немає (сезонне, разове), комора каже про це словами, а не вигаданим числом.
- Знає терміни. Від циклу залежить не лише «коли купити», а й «скільки має пролежати»: стеля зберігання виду ставить межу на цикл з чеків, а мовчання довше за два цикли читається як «перестав брати», не як «треба».
- Слухає гостя. «Вже купив», «лишилось дві», «вистачає на два дні», «сховати», дописаний руками вид, список на наступну покупку. Слово гостя лягає під його акаунт і переживає пристрій.
- Збирає кошик під потребу. Три входи в один конвеєр: сума («зібрати на 3 000 ₴», коридор ±10%), чужий кошик (зібраний руками або повтором) і текстовий список «молоко, хліб, щось до чаю». Привід («гості на шістьох», «у дорогу») міняє склад, а суму під привід агент пропонує сам, у межах, які тримає код.
- Дає заміни наперед. На кожен рядок з ризиком складається ланцюжок замін того ж виду, гість погоджує його один раз, і далі мандат їде збирачу в коментарі позиції. Погоджена заміна запам'ятовується по виду.
- Тримає економіку. Поріг безкоштовної доставки, вага, мінімум замовлення, крок продажу вагового товару, акційні звички (те, що гість бере лише по акції, їде лише з акцією), дешевша фасовка того ж виду.
- Питає, коли не знає. Два види томатів черрі під один намір, готова страва чи інгредієнти, «на подію готуєш сам?» Відповідь повертається в кошик без перезбірки, і зверх межі кошик не виходить.
- Бар окремо. Алкоголь беруть нерівно і не лише в «Сільпо», тож він живе своїм списком і в тижневий кошик не їде, але у привід потрапляє.
- Каже, звідки що взялось. Кожен рядок пояснює свою причину, кожен крок агента видно у трейсі: що планувала модель, що виконав код, що не знайшлось, що зрізано під межу і чому.
Агент за означенням Anthropic: план складає модель, виконує код, після кожної пачки кроків модель бачить результат і вирішує, що далі, а зупинку судить окремо.
- План. Модель бачить задачу, живі описи інструментів «Сільпо» і закритий словник кроків: 24 кроки у восьми фазах (місце, слот, історія, комора, наміри, полиця, рішення, економіка, кошик). Вона обирає, які необов'язкові кроки потрібні цьому гостю: пошук за артикулом з чека, дошук іншими словами, ланцюжок замін, повторний вибір. Валідатор ріже криве поштучно і називає причину; план з коду лишається відкатом і каже про себе банером.
- Виконання і ґрунт. Виконавець кладе факти в мішок, і кожна відповідь «Сільпо» стає ґрунтом для наступного оберту: скільки кандидатів, скільки своїх артикулів, скільки рядків, скільки грошей проти межі, які питання відкриті. Пачка, ґрунт, переплан, і так до «досить».
- Три петлі. Комора: після першої відмальовки модель вирішує, чого бракує стану дому (назвати вид, розсудити ритм, спитати гостя), і порожній план тут законна відповідь. Кошик: невиконане повертається планувальнику, він перевибирає адресно, за наміром. Дошук: рядок без збігу модель шукає сама, обираючи інструмент з дозволеного переліку.
- Зупинка і людина. Модель каже «стоп» і чому; суддя мети в коді перевіряє, що кожен намір гостя кудись дійшов: у рядок, у питання, у «не знайшлось». Людина стоїть на трьох точках: питання агента, екран замін, «Оформити».
- Запобіжники в коді, а не в промпті. Запис у чужий кошик, слот лише від «зараз», філія кошика проти філії плану, верхня межа суми, «слово гостя не ріжеться».
Усе через офіційний MCP-сервер «Сільпо»: 19 інструментів із 40. Їхні описи агент читає наживо при плануванні, тож зміна на боці «Сільпо» доїжджає до нього без правки коду.
| Інструмент | Для чого |
|---|---|
get_my_offline_orders, get_my_online_orders |
модель споживання: цикли, залишки, звичні кількості, ціна, яку бачили |
get_my_profile, get_my_food_restrictions |
вхід гостя (OAuth 2.1, токен лише в його браузері) і обмеження з профілю |
get_my_delivery_addresses, find_address, get_available_delivery_types, list_branches |
філія з адреси, спосіб доставки |
get_time_slots |
слот від поточного часу; його ж питають щогодинний знімок слотів і обхід каталогу |
find_products_batch |
пошук під намір: драбина звуження назви з чека, свій артикул за числом, дошук петлі |
get_products, get_categories |
щотижневий обхід каталогу 18 філій: карта видів (вузол дерева як відповідь «що це за вид») і нагрів кешу назв |
get_similar_products |
ланцюжок замін і дошук, коли пошук мовчить |
get_my_shopping_cart, get_shopping_cart_by_id |
вхід «чужий кошик»: сума після знижок, вага, пороги, галочки замін |
create_shopping_cart, add_or_update_cart_products, remove_cart_products |
запис кошика: дозвіл на запис дає лише передача, збірка писати не вміє |
update_shopping_cart |
слот і мандат збирачу; кошик перечитується після кожного запису |
Живий продукт: https://pantry.klimnyk.dev.
Відео-пітч:
https://youtu.be/MaYrDeVMxeA.
Презентація:
https://pantry-deck.mykhailo-klimnyk.workers.dev/.
Що спробувати: підключити акаунт «Сільпо», дочекатись, поки заповниться комора, натиснути «Зібрати кошик на суму», відповісти на питання агента, подивитись «Що зробив агент», погодити заміни і оформити. Кошик з'явиться в застосунку «Сільпо» з коментарями збирачу.
Без акаунта з історією комора порожня, і продукт каже, коли вона почне рахуватись. Це норма, а не збій.
- Час на замовлення. Було близько двадцяти хвилин руками. Міряється тривалістю прогону і кількістю правок гостя після збірки: кожна правка це промах моделі споживання, і їх видно в журналі прогонів.
- Частка замін, погоджених наперед, проти «не привозити» і дзвінка збирача. Це те, чого не дає жодна галочка в застосунку.
- Ціна прогону проти ціни дзвінка і недовезеної позиції: 2 центи, лічильник у продукті рахує токени в порту моделі, а не в місцях виклику.
- Інженерні числа, станом на 16.09: 3 760 тестів, 778 e2e проти прод-збірки на двох ширинах, мутації по детермінованому ядру 91% (6 161 з 6 797, без тестів — жодного). Пастки на промпти — 37 з 38 і 36 з 38 сценаріїв на двох моделях (pass^5), замір від 12.09: він ходить у чужу мережу за гроші, тож на пуш не ганяється, а хеші промптів кажуть, що з того дня жоден із них не зрушив. Живі числа на сторінці «Якість» у самому продукті.
- Список на наступну покупку одним віджетом. Наговорити, сфотографувати або набрати те, що треба купити, там, де замовляєш, а не на фото, папірцях і в чаті. Рядок їде з наступним кошиком, а після покупки лягає в комору.
- Синхронізація з календарем. Google Calendar і подібні: назва події і час, з явного дозволу гостя, без запису і без копії в нас. Дає дві речі — привід наперед (день народження, свято, тиждень у поїздці: кошик готується за кілька днів до події, а не в мить, коли гість сів замовляти) і слот у вільне вікно, а не в годину, на яку в гостя зустріч.
- Агент збирача. Окремий агент або workflow на боці «Сільпо»: перевіряє наявність і заміни замовлення на філії, бачить вимивання товару до слота і сповіщає збирача, коли потрібне рішення. Приклад схеми: https://pidsobka.m-klimnyk.workers.dev/, профіль «збирач замовлення».
- Чек після доставки замикає петлю. Що приїхало, лягає в комору назад, і наступний кошик рахується вже від нього.
- Перевірка наявності самих замін. Ланцюжок замін береться з полиці в момент збірки, а збирач читає його за години. Перед самим слотом варто перевіряти і рядок, і кожну ланку, щоб мандат не обіцяв зниклого. Потребує ендпоїнта «Сільпо» на замовлення після оформлення; мандат у коментарі вже працює.
- Поділитись кошиком посиланням (ідея з Discord хакатону). Сьогодні кнопка «Поділитись» надсилає текст із назвами, кількостями і картками на silpo.ua. Посилання, яке інший гість повторить одним дотиком, потребує збереженого кошика з публічною адресою і ендпоїнта «Сільпо», що покладе чужий перелік у свій кошик.
Postgres 18 · Python 3.14 · psycopg 3 · FastAPI · mcp 2.0 · Mistral Large 3 через AWS Bedrock, GPT-5.6 Luna з ключем гостя · Svelte 5 · Vite 8 · TypeScript 7
Без ORM, без Tailwind, без UI-бібліотек. Внутрішні імена в коді лишились
komora: продукт перейменовано на ПанTry 10.09, а гість цих імен не бачить.
Понад 99% коду написав ШІ-агент. Власник продукту ставив задачі, ухвалював рішення і перевіряв результат руками на своєму акаунті. Саме тому тести, мутації і пастки на промпти тут не декорація: авторство сильне рівно настільки, наскільки видно, чим його перевірено.
| Ярус | Що | Де |
|---|---|---|
| 1 | Фронт і проксі /api на один origin |
Cloudflare Worker |
| 2 | Живий API | Fedora за reverse-SSH тунелем на Oracle |
| 3 | Інференс | Bedrock; Luna в OpenAI ключем гостя |
docs/graph-report.md— карта репозиторію: спільноти, хаби, аудит витягу. Будується заново перед кожною публікацією, тож описує рівно це дерево, а не сусіднєdocs/licenses.md— перелік ліцензій, збирається з реально встановлених пакетів і звіряється в CI
Робочі нотатки (mcp-facts.md, measured.md, setup.md, deploy.md,
history.md) лишаються в приватному репозиторії: там живі виклики чужого API,
внутрішні заміри і хронологія роботи.
Коментарі і докстрінги з коду зняті механічно на публікації
(scripts/public_tree.py); types.ts і facts.ts перегенеровано на цьому ж
дереві. Кожне зняття доведене: для Python -- рівність AST, для фронта -- друк
AST і компіляція компонентів, для конфігів -- рівність розібраних даних.
Проєкт під Apache-2.0. Перелік використаних ліцензій:
docs/licenses.md, збирається з реально встановлених
пакетів і звіряється в CI.
Зображення товарів і бренд «Сільпо» не хостимо: лише посилання на їхній CDN. Логотип «Сільпо» не використовуємо.
Токен «Сільпо» живе в браузері гостя, не в нашій базі. Історія покупок
зберігається під відбитком акаунта без імені, телефону, адреси і без
branchId, який вказує на район. Аргументи викликів MCP редагуються перед
записом у журнал і трейс. Фікстури анонімізовані детермінованим скриптом.
