<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>memory &amp;mdash; Цифровой дворник</title>
    <link>https://articles.clr58.ru/tag:memory</link>
    <description>Практические заметки о сетях, self-hosting, виртуализации, мониторинге, автоматизации и локальном ИИ.</description>
    <pubDate>Wed, 30 Sep 2026 01:15:13 +0000</pubDate>
    <item>
      <title>Почём токены для памяти: граф против контекста</title>
      <link>https://articles.clr58.ru/graph-token-cost</link>
      <description>&lt;![CDATA[Обложка&#xA;&#xA;Есть момент, когда агент перестаёт влезать в собственный промпт. Начинаешь с трёх заметок, через месяц их шестьдесят, и каждый старт беседы ты уже платишь за то, чтобы модель просто прочитала твою же память — до того, как сделает хоть что-то полезное.&#xA;&#xA;Я упёрся в это ровно тогда, когда закончил серию из одиннадцати статей и понял, что помнить их все «в голове» (в контексте) больше нельзя. Пришлось решать: тащить всё в промпт и платить за каждый запрос, или построить граф знаний и платить за то, чтобы в него что-то положить.&#xA;&#xA;Дальше — реальные цифры с моей домашней лабы. Не синтетика, а замеры на живом ассистенте.&#xA;&#xA;Два способа помнить&#xA;&#xA;Плоская память. Всё лежит в markdown-файлах, которые подгружаются в контекст. Модель видит их напрямую, но каждый запрос начинается с того, что весь этот текст прогоняется через токенайзер. Чем больше помнишь — тем дороже каждый вопрос, даже «как дела».&#xA;&#xA;Графовая память. Текст прогоняется через LLM один раз — из него вытаскиваются сущности и связи («gemma3 работает на ollama», «gemma3 не поддерживает tools»). Это складывается в граф. При вопросе ищешь по смыслу стартовый узел и разворачиваешь соседей. Платишь за инжест, поиск почти бесплатный.&#xA;&#xA;Два способа помнить: плоская память против графа&#xA;&#xA;Какие бывают графы&#xA;&#xA;Три уровня, от простого к навороченному — все три я разворачивал за один день и гонял на одной и той же статье.&#xA;&#xA;Самописный SQLite-граф. Две таблицы — сущности и связи, обход соседей пишешь сам. Ноль инфраструктуры, полный контроль, читаемый вывод. Минус: никакой темпоральности — граф не помнит, что факт был правдой только до вчера, и всё извлечение вручную.&#xA;&#xA;Property graph (FalkorDB, Neo4j). Настоящий графовый движок, запросы на Cypher, быстрый обход на любую глубину, индексы. Это как SQL, только для связей. FalkorDB легче Neo4j — это Redis с графовым модулем, поднимается одной командой.&#xA;&#xA;Темпоральный граф (Graphiti, Microsoft GraphRAG). Уровень выше: ты не строишь граф вручную, а скармливаешь текст — LLM сам вытаскивает сущности, факты и связи. Главное отличие — битемпоральность: граф помнит не только «что правда сейчас», но и «что было правдой раньше», и откуда каждый факт взялся. Для ассистента, который живёт неделями и чьи знания устаревают, это решающее свойство.&#xA;&#xA;Как это ставится&#xA;&#xA;Честный путь по моему опыту.&#xA;&#xA;FalkorDB — одна команда:&#xA;&#xA;docker run -d --name falkordb -p 6379:6379 falkordb/falkordb&#xA;&#xA;Graphiti поверх него — Python-пакет:&#xA;&#xA;pip install graphiti-core[falkordb]&#xA;&#xA;Дальше конфиг: какая LLM извлекает сущности, какие эмбеддинги, куда складывать. Грабли, на которые я наступил, чтобы ты не наступал: у DeepSeek нужно явно задать «маленькую» модель (иначе Graphiti шлёт дефолтную OpenAI-модель и ловит 400); эмбеддеру нужен непустой api_key, даже если он никем не проверяется; кириллические названия связей движок не переваривает — их надо класть в свойство ребра, а не в тип.&#xA;&#xA;SQLite-граф ставить нечего — это двадцать строк на Python.&#xA;&#xA;Дальше — замеры, ради которых всё затевалось.&#xA;&#xA;Замер 1: начало беседы&#xA;&#xA;Считаем, сколько токенов уходит на старт, до первого вопроса.&#xA;&#xA;Файлы, которые грузятся всегда: долговременная память, заметки по инструментам, правила поведения — примерно 16–20 тысяч токенов. Это цена «проснуться и вспомнить, кто я».&#xA;&#xA;А вот дальше развилка. Дневные заметки копятся. Вся история — это уже 61 тысяча токенов и растёт каждый день. В плоской памяти у тебя два пути, оба плохие: либо грузить всё (каждый запрос дорожает на десятки тысяч токенов), либо обрезать старое (и агент «забывает» месяц назад).&#xA;&#xA;Замер 2: сколько стоит положить знание в граф&#xA;&#xA;Кладём в граф короткий эпизод — 483 символа текста, пять предложений про то, что мы подняли графовую память.&#xA;&#xA;Что происходит под капотом: LLM несколько раз прогоняет текст — извлекает сущности, потом связи, потом сверяет с уже существующими узлами, не дубликаты ли это. Итого 8 вызовов LLM, 13 тысяч входных и 1 тысяча выходных токенов, 13 секунд.&#xA;&#xA;В деньгах — $0.0021 за эпизод на дешёвой модели. Это и есть цена знания: одна заметка ≈ полцента.&#xA;&#xA;Статья из серии (6–7 тысяч символов) обходится в $0.03. Вся серия из одиннадцати статей — $0.33.&#xA;&#xA;Замер 3: сколько стоит вспомнить&#xA;&#xA;Вопрос «какая локальная модель используется для эмбеддингов» к графу.&#xA;&#xA;Ноль вызовов LLM. $0. Ноль целых три десятых секунды.&#xA;&#xA;Потому что поиск по графу — это не LLM, а эмбеддинги (локальная модель, бесплатно) плюс обход связей в базе. LLM подключается только на этапе занесения знания, а не на каждом вопросе.&#xA;&#xA;Это главный разворот по сравнению с плоской памятью: там ты платишь за знание при каждом обращении к нему, здесь — один раз при занесении.&#xA;&#xA;Замер 4: субагенты&#xA;&#xA;Запуск субагента — это отдельная история, и тут граф ничего не экономит напрямую: субагент всё равно получает свой контекст и свой промпт. Каждый субагент — это десятки тысяч токенов входного контекста только на то, чтобы он понял задачу.&#xA;&#xA;Что реально меняет граф: субагент может не тащить с собой всю историю. Достаточно дать ему узкий контекст задачи и, если нужно, пару фактов из графа точечным поиском — а не вываливать на него шестьдесят тысяч токенов прошлого.&#xA;&#xA;А если это кодинг-агент&#xA;&#xA;Тот же самый граф можно повесить не только на ассистента, но и на кодинг-агентов — Codex, Claude Code, Cursor, OpenCode. Идея ровно та же, что с заметками: кодинг-агент не держит в голове всю кодовую базу, а спрашивает граф, куда смотреть.&#xA;&#xA;Общий знаменатель — MCP. Все четверо умеют подключать MCP-серверы как инструменты, а у Graphiti такой сервер уже есть из коробки. Разница только в конфиге:&#xA;&#xA;Codex — подключить Graphiti как MCP memory-инструмент; агент зовёт его вместо того, чтобы перечитывать файлы.&#xA;Claude Code — claude mcp add или hook, который при старте задачи дергает граф за контекстом.&#xA;Cursor — .cursor/mcp.json, граф становится обычным источником @-упоминаний.&#xA;OpenCode — тот же MCP, конфиг в json.&#xA;&#xA;Что кладём в граф: карту репозитория — файлы, модули, функции, классы и связи между ними (кто кого импортирует, кто кого вызывает), плюс историю решений «почему сделали так, а не иначе».&#xA;&#xA;Кодинг-агенты подключаются к графу через MCP&#xA;&#xA;Прогноз по токенам. Это уже не замер, а честная прикидка, но логика та же, что в замерах выше:&#xA;&#xA;Сейчас кодинг-агент на каждую задачу перечитывает дерево проекта и релевантные файлы — легко 50–100k входных токенов только на то, чтобы понять, где он вообще находится.&#xA;С графом он сперва спрашивает «какие модули связаны с этой функцией», получает точечный список из 5–15k токенов и читает только нужное. Поиск по графу, напомню, стоит $0 — это локальные эмбеддинги.&#xA;Итог: 60–80% экономии на входном контексте на каждой задаче. При активном кодинге это ощутимо — не десятки центов в день, а разы на месячной дистанции.&#xA;&#xA;Где экономия не сработает: если проект маленький и весь влезает в контекст целиком — граф не нужен. И сам инжест кодовой базы не бесплатен: гонять весь код через LLM для извлечения связей — дорого (у нас $0.0021 за полтысячи символов). Для кода разумнее гибрид: структуру (файлы, сигнатуры, импорты) снимать статическим анализом, а через LLM — только описания и решения. Тогда разовая цена индексации окупается за считанные дни активной работы.&#xA;&#xA;Точка окупаемости&#xA;&#xA;Граф начинает выигрывать, когда одни и те же знания спрашиваются повторно.&#xA;&#xA;Одна заметка = $0.0021 за инжест. Если факт из неё понадобится хотя бы пару раз, граф уже дешевле, чем каждый раз читать его в контексте. А главное — граф не растёт в промпте: тысячи сущностей стоят столько же при поиске, сколько и десять.&#xA;&#xA;Плоская память выигрывает ровно в одном случае: знаний мало, и они меняются редко. Тогда проще держать их в одном файле.&#xA;&#xA;Вывод&#xA;&#xA;Граф — это не «модно», это про то, где платить. Либо понемногу, но при каждом вопросе (контекст), либо один раз при занесении (граф). Для ассистента, который живёт неделями и накапливает опыт, второй вариант оказывается дешевле — и, что важнее, предсказуемее: стоимость вопроса не зависит от того, сколько ты всего знаешь.&#xA;&#xA;Теги: #llm #graphrag #memory #openclaw #selfhosting&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://paste.clr58.ru/post-graph-token-cost-digclean.jpg" alt="Обложка"></p>

<p>Есть момент, когда агент перестаёт влезать в собственный промпт. Начинаешь с трёх заметок, через месяц их шестьдесят, и каждый старт беседы ты уже платишь за то, чтобы модель просто прочитала твою же память — до того, как сделает хоть что-то полезное.</p>

<p>Я упёрся в это ровно тогда, когда закончил серию из одиннадцати статей и понял, что помнить их все «в голове» (в контексте) больше нельзя. Пришлось решать: тащить всё в промпт и платить за каждый запрос, или построить граф знаний и платить за то, чтобы в него что-то положить.</p>

<p>Дальше — реальные цифры с моей домашней лабы. Не синтетика, а замеры на живом ассистенте.</p>

<h2 id="два-способа-помнить">Два способа помнить</h2>

<p><strong>Плоская память.</strong> Всё лежит в markdown-файлах, которые подгружаются в контекст. Модель видит их напрямую, но каждый запрос начинается с того, что весь этот текст прогоняется через токенайзер. Чем больше помнишь — тем дороже каждый вопрос, даже «как дела».</p>

<p><strong>Графовая память.</strong> Текст прогоняется через LLM один раз — из него вытаскиваются сущности и связи («gemma3 работает на ollama», «gemma3 не поддерживает tools»). Это складывается в граф. При вопросе ищешь по смыслу стартовый узел и разворачиваешь соседей. Платишь за инжест, поиск почти бесплатный.</p>

<p><img src="https://paste.clr58.ru/graph-vs-flat.jpg" alt="Два способа помнить: плоская память против графа"></p>

<h2 id="какие-бывают-графы">Какие бывают графы</h2>

<p>Три уровня, от простого к навороченному — все три я разворачивал за один день и гонял на одной и той же статье.</p>

<p><strong>Самописный SQLite-граф.</strong> Две таблицы — сущности и связи, обход соседей пишешь сам. Ноль инфраструктуры, полный контроль, читаемый вывод. Минус: никакой темпоральности — граф не помнит, что факт был правдой только до вчера, и всё извлечение вручную.</p>

<p><strong>Property graph (FalkorDB, Neo4j).</strong> Настоящий графовый движок, запросы на Cypher, быстрый обход на любую глубину, индексы. Это как SQL, только для связей. FalkorDB легче Neo4j — это Redis с графовым модулем, поднимается одной командой.</p>

<p><strong>Темпоральный граф (Graphiti, Microsoft GraphRAG).</strong> Уровень выше: ты не строишь граф вручную, а скармливаешь текст — LLM сам вытаскивает сущности, факты и связи. Главное отличие — битемпоральность: граф помнит не только «что правда сейчас», но и «что было правдой раньше», и откуда каждый факт взялся. Для ассистента, который живёт неделями и чьи знания устаревают, это решающее свойство.</p>

<h2 id="как-это-ставится">Как это ставится</h2>

<p>Честный путь по моему опыту.</p>

<p><strong>FalkorDB</strong> — одна команда:</p>

<pre><code>docker run -d --name falkordb -p 6379:6379 falkordb/falkordb
</code></pre>

<p><strong>Graphiti</strong> поверх него — Python-пакет:</p>

<pre><code>pip install graphiti-core[falkordb]
</code></pre>

<p>Дальше конфиг: какая LLM извлекает сущности, какие эмбеддинги, куда складывать. Грабли, на которые я наступил, чтобы ты не наступал: у DeepSeek нужно явно задать «маленькую» модель (иначе Graphiti шлёт дефолтную OpenAI-модель и ловит 400); эмбеддеру нужен непустой api_key, даже если он никем не проверяется; кириллические названия связей движок не переваривает — их надо класть в свойство ребра, а не в тип.</p>

<p><strong>SQLite-граф</strong> ставить нечего — это двадцать строк на Python.</p>

<p>Дальше — замеры, ради которых всё затевалось.</p>

<h2 id="замер-1-начало-беседы">Замер 1: начало беседы</h2>

<p>Считаем, сколько токенов уходит на старт, до первого вопроса.</p>

<p>Файлы, которые грузятся всегда: долговременная память, заметки по инструментам, правила поведения — примерно <strong>16–20 тысяч токенов</strong>. Это цена «проснуться и вспомнить, кто я».</p>

<p>А вот дальше развилка. Дневные заметки копятся. Вся история — это уже <strong>61 тысяча токенов</strong> и растёт каждый день. В плоской памяти у тебя два пути, оба плохие: либо грузить всё (каждый запрос дорожает на десятки тысяч токенов), либо обрезать старое (и агент «забывает» месяц назад).</p>

<h2 id="замер-2-сколько-стоит-положить-знание-в-граф">Замер 2: сколько стоит положить знание в граф</h2>

<p>Кладём в граф короткий эпизод — 483 символа текста, пять предложений про то, что мы подняли графовую память.</p>

<p>Что происходит под капотом: LLM несколько раз прогоняет текст — извлекает сущности, потом связи, потом сверяет с уже существующими узлами, не дубликаты ли это. Итого <strong>8 вызовов LLM</strong>, <strong>13 тысяч входных и 1 тысяча выходных токенов</strong>, <strong>13 секунд</strong>.</p>

<p>В деньгах — <strong>$0.0021</strong> за эпизод на дешёвой модели. Это и есть цена знания: одна заметка ≈ полцента.</p>

<p>Статья из серии (6–7 тысяч символов) обходится в <strong>$0.03</strong>. Вся серия из одиннадцати статей — <strong>$0.33</strong>.</p>

<h2 id="замер-3-сколько-стоит-вспомнить">Замер 3: сколько стоит вспомнить</h2>

<p>Вопрос «какая локальная модель используется для эмбеддингов» к графу.</p>

<p><strong>Ноль вызовов LLM. $0. Ноль целых три десятых секунды.</strong></p>

<p>Потому что поиск по графу — это не LLM, а эмбеддинги (локальная модель, бесплатно) плюс обход связей в базе. LLM подключается только на этапе занесения знания, а не на каждом вопросе.</p>

<p>Это главный разворот по сравнению с плоской памятью: там ты платишь за знание <strong>при каждом обращении к нему</strong>, здесь — <strong>один раз при занесении</strong>.</p>

<h2 id="замер-4-субагенты">Замер 4: субагенты</h2>

<p>Запуск субагента — это отдельная история, и тут граф ничего не экономит напрямую: субагент всё равно получает свой контекст и свой промпт. Каждый субагент — это десятки тысяч токенов входного контекста только на то, чтобы он понял задачу.</p>

<p>Что реально меняет граф: субагент может не тащить с собой всю историю. Достаточно дать ему узкий контекст задачи и, если нужно, пару фактов из графа точечным поиском — а не вываливать на него шестьдесят тысяч токенов прошлого.</p>

<h2 id="а-если-это-кодинг-агент">А если это кодинг-агент</h2>

<p>Тот же самый граф можно повесить не только на ассистента, но и на кодинг-агентов — Codex, Claude Code, Cursor, OpenCode. Идея ровно та же, что с заметками: кодинг-агент не держит в голове всю кодовую базу, а спрашивает граф, куда смотреть.</p>

<p><strong>Общий знаменатель — MCP.</strong> Все четверо умеют подключать MCP-серверы как инструменты, а у Graphiti такой сервер уже есть из коробки. Разница только в конфиге:</p>
<ul><li><strong>Codex</strong> — подключить Graphiti как MCP memory-инструмент; агент зовёт его вместо того, чтобы перечитывать файлы.</li>
<li><strong>Claude Code</strong> — <code>claude mcp add</code> или hook, который при старте задачи дергает граф за контекстом.</li>
<li><strong>Cursor</strong> — <code>.cursor/mcp.json</code>, граф становится обычным источником <code>@</code>-упоминаний.</li>
<li><strong>OpenCode</strong> — тот же MCP, конфиг в json.</li></ul>

<p><strong>Что кладём в граф:</strong> карту репозитория — файлы, модули, функции, классы и связи между ними (кто кого импортирует, кто кого вызывает), плюс историю решений «почему сделали так, а не иначе».</p>

<p><img src="https://paste.clr58.ru/graph-mcp-agents.jpg" alt="Кодинг-агенты подключаются к графу через MCP"></p>

<p><strong>Прогноз по токенам.</strong> Это уже не замер, а честная прикидка, но логика та же, что в замерах выше:</p>
<ul><li>Сейчас кодинг-агент на каждую задачу перечитывает дерево проекта и релевантные файлы — легко <strong>50–100k входных токенов</strong> только на то, чтобы понять, где он вообще находится.</li>
<li>С графом он сперва спрашивает «какие модули связаны с этой функцией», получает точечный список из <strong>5–15k токенов</strong> и читает только нужное. Поиск по графу, напомню, стоит <strong>$0</strong> — это локальные эмбеддинги.</li>
<li>Итог: <strong>60–80% экономии на входном контексте</strong> на каждой задаче. При активном кодинге это ощутимо — не десятки центов в день, а разы на месячной дистанции.</li></ul>

<p><strong>Где экономия не сработает:</strong> если проект маленький и весь влезает в контекст целиком — граф не нужен. И сам инжест кодовой базы не бесплатен: гонять весь код через LLM для извлечения связей — дорого (у нас $0.0021 за полтысячи символов). Для кода разумнее гибрид: структуру (файлы, сигнатуры, импорты) снимать статическим анализом, а через LLM — только описания и решения. Тогда разовая цена индексации окупается за считанные дни активной работы.</p>

<h2 id="точка-окупаемости">Точка окупаемости</h2>

<p>Граф начинает выигрывать, когда одни и те же знания спрашиваются повторно.</p>

<p>Одна заметка = $0.0021 за инжест. Если факт из неё понадобится хотя бы пару раз, граф уже дешевле, чем каждый раз читать его в контексте. А главное — граф не растёт в промпте: тысячи сущностей стоят столько же при поиске, сколько и десять.</p>

<p>Плоская память выигрывает ровно в одном случае: знаний мало, и они меняются редко. Тогда проще держать их в одном файле.</p>

<h2 id="вывод">Вывод</h2>

<p>Граф — это не «модно», это про то, где платить. Либо понемногу, но при каждом вопросе (контекст), либо один раз при занесении (граф). Для ассистента, который живёт неделями и накапливает опыт, второй вариант оказывается дешевле — и, что важнее, предсказуемее: стоимость вопроса не зависит от того, сколько ты всего знаешь.</p>

<p>Теги: <a href="https://articles.clr58.ru/tag:llm" class="hashtag"><span>#</span><span class="p-category">llm</span></a> <a href="https://articles.clr58.ru/tag:graphrag" class="hashtag"><span>#</span><span class="p-category">graphrag</span></a> <a href="https://articles.clr58.ru/tag:memory" class="hashtag"><span>#</span><span class="p-category">memory</span></a> <a href="https://articles.clr58.ru/tag:openclaw" class="hashtag"><span>#</span><span class="p-category">openclaw</span></a> <a href="https://articles.clr58.ru/tag:selfhosting" class="hashtag"><span>#</span><span class="p-category">selfhosting</span></a></p>
]]></content:encoded>
      <guid>https://articles.clr58.ru/graph-token-cost</guid>
      <pubDate>Thu, 27 Aug 2026 19:39:42 +0000</pubDate>
    </item>
  </channel>
</rss>