Пам'ять для Claude Code: D1 + KV + Vectorize на практиці
Персональна пам’ять для Claude Code: Cloudflare Worker із D1, KV та Vectorize, який замінює ручне ведення MEMORY.md і дає агентам семантичний пошук, проектний контекст і синхронізацію з GitHub Issues.
Щоранку одне й те саме. Відкриваю Claude Code, вставляю три абзаци контексту про поточний проект. Які ендпоінти є, що деплоїв минулого разу, яка структура бази. Через годину нова сесія, копіюю знову. На п’ятий раз я зрозумів: агент, який не пам’ятає мій проект, змушує мене бути його пам’яттю.
Чому MEMORY.md не вистачає
MEMORY.md це файл на 200 рядків максимум. Плоский текст без структури. Зв’язків між проектами нуль, а замість пошуку за змістом — grep по точних словах. Для одного pet project вистачає, для трьох паралельних — ні.
Я вже пробував GitHub Projects як пам’ять для AI-агента. Працювало краще за голий файл, але семантичного пошуку там немає. Хочеш знайти “як я налаштовував авторизацію”? Шукай точні слова. Записав “Supabase JWT setup”, а питаєш “як працює auth” — результатів нуль.
Між сесіями зв’язок губиться. Агент не знає, що вчора ти фіксив баг у тому ж модулі, що сьогодні хочеш розширити. Кожна сесія як чистий аркуш.
Модель даних: 5 сутностей
Я зупинився на п’яти сутностях. Не три, не десять. П’ять — я перевірив.
Сутності
Memories: ядро системи. Текстовий запис з importance від 1 до 5, теги, категорія. TTL залежить від importance: факт з importance 1 живе тиждень, критичне рішення з importance 5 зберігається назавжди. Кожен memory прив’язаний до проекту.
Project state: goals, поточний контекст як JSON, активні рішення. Агент бере стейт на старті сесії і одразу розуміє, де ми зупинились.
Tasks: я зробив їх дзеркалом GitHub Issues. Єдине джерело правди для того, що потрібно зробити. Створюю task в пам’яті — з’являється issue. Закриваю issue — task оновлюється.
Artifacts: посилання на конкретні файли, конфіги, сніпети коду, URL-и. Щоб агент міг знайти “той Dockerfile, який я правив для Railway” без перебору всього репозиторію.
Sessions і events: лог того, що відбувалось. Яка сесія, які дії, які результати. Для розуміння контексту, не для аудиту.
Інфраструктура: один Worker, zero-ops
Чому Cloudflare, а не VPS? Бо я не хочу думати про сервер. Worker на Hono запускається за мілісекунди, масштабується сам, коштує копійки на моїх обсягах.
D1: SQLite на edge. П’ять таблиць, прості JOIN-и, все працює. Для персонального використання більше не потрібно.
KV: кеш перед D1. Memories кешуються на 5 хвилин, projects на 2 хвилини. Більшість запитів агента (“дай контекст проекту”) йдуть з кешу, а не з бази.
Vectorize: векторний індекс для семантичного пошуку. Я генерую ембедінги через Gemini API. Записую memory, створюю ембедінг, зберігаю у Vectorize. Питаю “як налаштовував auth” і отримую записи про JWT, Supabase, JWKS — навіть коли слова “auth” ніде немає.
І весь цей стек — один Worker, один wrangler deploy. Без Docker і без systemd.
Skill: тригери і оркестрація
Skill активується на конкретні фрази. “Запам’ятай” означає збережи. “Згадай” означає знайди. “Контекст проекту” завантажує стейт.
Під капотом три ролі агентів і шість фаз оркестрації. Архітектура шарів AI-агента працює і тут, тільки шар один — пам’ять.
Scout: read-only агент на Explore (opus). Збирає контекст: які memories є, який стейт проекту, що змінилось.
Worker: general-purpose агент (opus), який робить реальну роботу. Створює записи, оновлює стейт, синхронізує tasks.
Analyst: general-purpose агент (sonnet). Перевіряє: чи не дублюється memory, чи правильний importance, чи актуальний стейт. Як у консиліумі з трьома агентами — різні ролі дають різні перспективи.
Шість фаз оркестрації:
1. Context → Scout збирає memories, project state, останні events 2. Plan → Worker аналізує контекст, визначає дії 3. Delegate → Worker розподіляє підзадачі між агентами → Analyst отримує задачу на валідацію 4. Observe → Analyst перевіряє: дублі? importance? актуальність? 5. Adapt → Worker записує в D1 + оновлює KV кеш + Vectorize ембедінг Persist якщо Analyst знайшов проблему → Worker адаптує 6. Report → Worker формує відповідь користувачу
// Потік даних: Scout ──→ Worker ──→ Analyst ──→ Worker ──→ D1/KV/Vectorize
GitHub sync: bidirectional webhook
Я налаштував webhook в обидва боки.
Створюю task через агента → Worker відправляє запит на GitHub API → з’являється issue. Хтось коментує або закриває issue → webhook приходить на Worker → task оновлюється в D1. Навіщо дублювати вручну?
Я вже використовував GitHub Issues як контекст проекту. Тепер issues не єдине джерело контексту, а частина ширшої системи. Tasks + memories + project state разом дають повну картину.
Єдиний source of truth. Я більше не синхронізую вручну.
Semantic search vs. grep
MEMORY.md + grep: шукаю “авторизація”, знаходжу тільки рядки зі словом “авторизація”. Записав як “Supabase JWT”? Не знайду.
Vectorize + Gemini embeddings: шукаю “як працює auth”, отримую записи про JWT setup, JWKS конфіг, Supabase tokens. Пошук за змістом, не за буквами.
Я обрав Gemini, бо у free tier достатньо для персонального використання. Хочеш інший провайдер — заміни, інтерфейс один: текст → вектор.
| Підхід | Пошук | Cross-project | GitHub sync | Self-hosted | Setup |
|---|---|---|---|---|---|
| MEMORY.md | grep (точний збіг) | Ні | Ні | Файл в репо | Нульова |
| GitHub Projects | API search (keyword) | Через organization | Нативний | GitHub SaaS | Низька |
| claude-mem | SQLite FTS | Так | Ні | Локальний SQLite | Низька |
| Mem0 | Семантичний (vector) | Так | Ні | Cloud / self-host | Середня |
| agent-memory (CF) | Семантичний (Vectorize) | Так | Bidirectional webhook | Cloudflare Worker | Середня |
Запит: "як я налаштовував деплой"
MEMORY.md grep:
"деплой" → 2 рядки (якщо слово є)
Semantic search:
→ Railway конфіг для backend
→ Dockerfile зміни від 12 березня
→ Environment variables для Supabase
→ Проблема з портом, яку фіксив тиждень тому
Чотири релевантних результати замість двох рядків з точним збігом.
Коли НЕ потрібно
Ця система це overhead для простих випадків.
Рідкісне використання Claude Code на одному проекті. Відкриваєш раз на тиждень для одного репозиторію? MEMORY.md вистачить. Серйозно. Три хвилини на копіпаст контексту не варті окремого Worker.
Команда більше однієї людини. Зараз це single-user рішення. Немає namespace-ів, немає access control. Для команди потрібен інший підхід.
Статичний контекст. Проект не змінюється тижнями — semantic search не дасть переваги над простим файлом. Пам’ять корисна, коли контекст рухається.
Що далі
MCP-сервер. Зараз skill працює через HTTP запити до Worker. MCP дасть нативну інтеграцію з Claude Code, менше glue code, простіший setup.
Compression sessions. Старі memories з низьким importance можна стискати: десять записів → один summary. Менше шуму при пошуку.
Multi-user namespace. Коли це стане корисним комусь ще — додати tenant isolation. Різні D1 databases per user, той самий Worker.
Я зрозумів: пам’ять — не фіча. Мінімальна вимога для того, щоб агент працював як помічник, а не як калькулятор із щоразу чистою стрічкою.
FAQ
Скільки коштує Cloudflare для цього? На персональних обсягах безкоштовно. Free tier D1: 5 GB storage, 5M reads/day. Free tier KV: 100K reads/day. Vectorize: 5M stored vectors. Я використовую менше 1% від лімітів.
Чи можна без Gemini для ембедінгів? Так. Gemini можна замінити на OpenAI embeddings, Cohere, або Cloudflare Workers AI (модель bge-base-en). Інтерфейс один: текст → вектор. Провайдер це деталь реалізації.
Як мігрувати з MEMORY.md? Парсиш файл, розбиваєш на логічні блоки, кожен блок стає memory із відповідним importance і тегами. Скрипт на 50 рядків. Або починаєш з нуля — я так і зробив.
Що буде, якщо Worker впаде? Claude Code продовжить працювати, просто без пам’яті. Як раніше. Дані не втрачуються. D1 бекапиться автоматично, KV працює з eventual consistency, але для кешу це ок.
Читайте також: GitHub Projects як пам’ять для AI-агента, Контекст проєкту в GitHub Issues