Read in:
Русский

Звонки в базу знаний

Krisp записывает ваши звонки. LLM-пайплайн превращает их в связную базу знаний: заметки звонков, глоссарий терминов, дневные заметки с чекбоксами задач и растущие логи тем. Не «summary плюс чат-бот», а граф, который прирастает с каждым звонком.

В статье:

Что получается на выходе

Каждый звонок превращается в набор связанных заметок, и база растёт с каждым новым:

  • заметка-транскрипт — сырой дословный транскрипт из Krisp, проверяемый источник;
  • заметка звонка — выведенное название, сильный первый абзац, ссылка на сырой транскрипт и разбор, где у каждой темы однострочная выжимка, а под ней дословная цитата из транскрипта со ссылкой-таймрейнджем;
  • заметки-концепты на людей, инструменты, проекты и термины, что в нём всплыли — у каждой алиасы и упоминания, которые цитируют тот самый сегмент, где термин прозвучал;
  • дневная заметка — сверху чекбоксы задач, ниже датированный лог дня;
  • логи тем для сквозных сюжетов — растут дописыванием, когда тема возвращается.

Это дёшево: около 5 центов за звонок в LLM-вызовах, примерно 15 центов за длинный звонок на 50 минут. Повторные запуски бесплатны, если кешировать ответы.

Разница с «summary плюс чат-бот» видна на втором звонке. Пересказ умирает после прочтения. Здесь одно и то же знание живёт в одной заметке и обрастает свидетельствами. В демо-прогоне ниже заметка проекта «Hermes» собрала три упоминания из трёх разных звонков, и каждое добавило новый ракурс: сначала объект для тестирования, потом «сильный клон OpenClaw», потом агент, который ведёт конспекты в Obsidian. Эту заметку никто не писал. Она выросла.

Как это работает

Две техники заметок

База держится на двух привычках ведения заметок, обе автоматизированы.

Дневные заметки: чекбоксы сверху, лог снизу, без итогов. На каждый календарный день — одна заметка. Сверху список задач: по чекбоксу на каждое обязательство из звонков этого дня, с владельцем и ссылкой на звонок-источник. Ниже, под ## Лог, — по записи на звонок: время, ссылка, суть одной строкой со ссылками на ключевые концепты. Никакого абзаца «итоги дня»: лог и есть итоги.

---
title: "2026-06-19, пятница"
created_at: "2026-06-19T00:00:00+07:00"
type: daily
calls_count: 2
---
- [ ] Настя: составить список источников поиска кандидатов ([[2026-06-19_ai-agenty-hr-sourcing-automation]])
- [ ] Speaker 3: созвониться с Юлией по автоматизации маркетинга ([[...]])

## Лог

- 15:37 [[2026-06-19_demo-prodazhnik-avtomatizatsiya|Запуск демо-продажника]] — ...
- 20:01 [[2026-06-19_ai-agenty-hr-sourcing-automation|AI-агенты для HR]] — ...

Если на звонке прозвучало «сделаю завтра», чекбокс попадает в заметку следующего дня. Поэтому у дня без звонков всё равно может быть дневная заметка: в ней живёт задача, перенесённая со вчера. На опубликованной странице чекбоксы интерактивны для админа сайта: день закрывается прямо в браузере, состояние сохраняется в заметку.

Логи тем: только дописывание, датированные заголовки. Когда тема возвращается из звонка в звонок, у неё появляется лог. Каждое новое упоминание дописывается под заголовком ### [[YYYY-MM-DD]] со ссылкой на дневную заметку. Старые записи не переписываются, поэтому заметка читается как история мысли:

### [[2026-06-19]]
Так здесь называют вариант поставки, при котором система разворачивается
на собственных серверах компании. ([[заметка звонка]], 46:14)

### [[2026-06-26]]
На такой коробке с агентами можно строить сервисы и даже
«настоящую компанию». ([[заметка звонка]], 13:01)

### [[2026-06-30]]
Продукт, который собеседник заканчивает и планирует тестировать. (...)

Это лог темы из демо-прогона: каждое упоминание на своей датированной строке, идея на глазах эволюционирует от звонка к звонку.

Пайплайн

Запустить можно двумя способами. Отдельный способ — один Python-скрипт (build_vault.py), который прогоняете по пачке транскриптов: годится для разового прогона и чтобы понять стадии. Способ в духе trip2g — событийный каскад fleet: три связанные заметки-роли, каждую будит change-webhook на заметке, которую записала предыдущая стадия. Кладёте сырой транскрипт в базу — и база собирает себя сама. Работа одна и та же, каскад лишь вешает стадии на события изменения заметок вместо цикла.

Вся LLM-работа на gpt-5.4-mini. Модель выиграла у более дешёвой nano на каждой стадии: стабильнее границы тем (совпадение между прогонами 75% против 67%), нет мусорных концептов, нет выдуманных таймкодов.

Стадия 1 — Ingest (executor: code, без LLM, единственная привязанная к источнику). Python-роль забирает сырые звонки из Krisp API и пишет каждый дословно как заметку в transcripts/. Только эта стадия знает про Krisp; всё, что дальше, от источника не зависит. Заметка-транскрипт — проверяемый источник истины, и разбор ссылается на неё, поэтому любое утверждение можно сверить с сырыми словами. Время берётся из id звонка, а не из часов: Krisp-id — это UUIDv7 с миллисекундным таймстемпом в старших битах, поэтому 019f178c декодируется в 2026-06-30 08:01 UTC, по часовому поясу пользователя — 15:01. Это единственный источник для created_at, сортировки и раскладки по дням. Локальные часы и mtime файлов врут, id — нет.

Стадия 2 — Разметка тем. Change-webhook на transcripts/** будит эту роль, когда появляется новый транскрипт. Она читает транскрипт и размечает границы тем промптом крупной гранулярности: отмечать только крупные смены темы, таймкоды брать дословно, small talk в начале — одна тема. Тем же проходом выводится название и делается попытка назвать спикеров: календарному названию из Krisp верить нельзя. Выведенные метаданные получают title_source: inferred и needs_review: true, подтверждение — правкой заметки.

Стадия 3 — Извлечение и растаскивание заметок. Записанные сегменты будят последнюю роль. Она достаёт из каждого сегмента типизированные концепты (люди, организации, проекты, инструменты, термины), решения, открытые вопросы и задачи; только имена собственные, поэтому «новый сотрудник» — не сущность. Здесь же происходит кросс-звонковый дедуп, и это самая сложная часть: распознавание речи коверкает имена, и в прогоне встретились «Cloud Code» и «Клод Код» вместо Claude Code и «век ромбс» вместо Backrooms. Таблица алиасов бесплатно ловит точные повторы; остаток уходит в один reconcile-вызов на транскрипт — модель видит кандидатов с контекстом и существующий глоссарий и отвечает MERGE или NEW, и каждый merge учит таблицу новым написаниям. Дальше эта роль записывает результат чистым кодом: обновляет концепты, дописывает логи тем, пишет чекбоксы задач в дневную заметку и пишет заметку-разбор звонка, которая ссылается на транскрипт из первой стадии.

Провенанс через цитату, а не пересказ. Каждое утверждение в базе ссылается на источник, и цитата сама и есть источник: границы уже посчитаны, поэтому каждая тема вырезает свои точные строки транскрипта и вставляет их блокквотом со ссылкой-таймрейнджем. Однострочная выжимка модели стоит сверху как польза, дословная цитата снизу как доказательство, которое не может соврать. Упоминания концептов работают так же: цитируют сегмент, где термин всплыл. Это видно на заметке концепта CRISP из прогона: выжимка читается чисто, а в цитате под ней остаётся сырое распознавание речи («...прогоняю и закидываю, например, там в Charge 5 или в Cloud...»), так что ослышки видны в доказательстве и не протекают в синтез.

Итого: три роли, каждую будит заметка, которую записала предыдущая. Это догфудинг — собственные change-webhooks trip2g плюс fleet-исполнитель кода строят базу знаний из тех же заметок, в которых сами живут.

База — обычный сайт trip2g, поэтому навигация — это журнальные страницы плюс граф:

  • / — звонки, свежие сверху; карточка — первый абзац заметки, поэтому пайплайн пишет его как сильную выжимку в 2-3 предложения;
  • /daily — дни; в карточке видны чекбоксы дня;
  • /concepts — термины, отсортированные по mentions: самое обсуждаемое всплывает наверх;
  • /log — логи тем по числу записей.

Одна деталь контракта важна: ключ даты во frontmatter — created_at со строковым значением в RFC3339. Ключ date молча игнорируется, заметка падает на время синка — ломается и сортировка, и раскладка по дням.

Внутри заметок вбок ведут вики-ссылки: из записи дня — в звонок, из звонка — в концепт, из упоминания концепта — в другой звонок.

Как собрать такое себе

Понадобятся Krisp (или любой рекордер с транскриптами вида Speaker | MM:SS), ключ OpenRouter, Python и инстанс trip2g. Начните с отдельного скрипта, а на каскад переходите, когда всё заработает.

  1. Возьмите готовое. Весь пайплайн упакован в отдельный репозиторий krisp_knowledge. Склонируйте его, скопируйте .env.example в .env и впишите KRISP_TOKEN и OPENROUTER_API_KEY. В комплекте синтетический example/-волт, чтобы увидеть форму результата ещё до прогона по своим звонкам.
  2. Ingest (запись и хранение). Krisp ставится как виртуальный микрофон и динамик, поэтому пишет звонки из любого приложения и отдаёт транскрипты по ролям с таймкодами. Шаг забора тянет каждый звонок через Krisp API и пишет дословно как заметку transcripts/YYYY-MM-DD_slug.md. Время из id, а не из часов: первые 8 hex-символов, int(prefix, 16) << 16 даёт миллисекунды от эпохи, переведите в свой часовой пояс и используйте для created_at, имён файлов и раскладки по дням.
  3. Проверяйте вход. Если таймкоды встречаются реже, чем раз на ~20 строк, звонок в карантин: на дефектном входе модель выдумывает таймкоды, на нормальном — никогда.
  4. Сегментируйте. Один вызов gpt-5.4-mini на транскрипт: строки [MM:SS] тема, только крупные смены, между темами не меньше 2 минут, плюс строки TITLE / SLUG / SPEAKERS как fallback метаданных.
  5. Извлекайте. Один вызов на кусок в 8-16 минут: JSON типизированных концептов с алиасами, суть в 1-3 предложениях только из сказанного здесь, плюс задачи с владельцем и сроком.
  6. Склеивайте. Держите aliases.json в базе. Сначала точное совпадение, остаток — одним LLM-вызовом на транскрипт. Упоминания дописывайте в существующие заметки; тело заметки никогда не переписывайте.
  7. Собирайте и публикуйте. Папки (transcripts/, calls/, daily/, concepts/, log/), журнальные index.md, _header.md со списком навигации. У каждой заметки звонка во frontmatter transcript: "[[transcripts/...]]" и inline-ссылка на сырой источник. Синк в trip2g — плагином Obsidian или через CLI.
  8. Проверяйте. Откройте сайт, отметьте чекбоксы в дневной заметке, поправьте названия у заметок с needs_review. Ваши правки — контур подтверждения: пайплайн дописывает, вы корректируете.
  9. Сделайте событийным (по желанию). Превратите три стадии в заметки-роли fleet и повесьте change-webhooks: transcripts/** будит разметку тем, сегменты будят извлечение. Теперь достаточно положить сырой транскрипт в базу — остальное соберётся само.

Про бюджет: ставьте лимит расходов. При ~15 центах за длинный звонок пачка укладывается в несколько долларов, а повторные запуски бесплатны, если кешировать сырые ответы LLM по стадиям.

Стадии работают не только для звонков. К источнику привязан лишь ingest; сегментация, извлечение, дедуп и сборка подходят для любого длинного текста: книг, YouTube, тредов поддержки. В агентском рантайме trip2g (fleet) каждая стадия — заметка-роль, которую будит заметка, записанная предыдущей стадией, так что пайплайн живёт в той же базе, которую строит.