Продолжаем исследовать возможности технологии LLM для повышения эффективности работы человека-пользователя и работы человека-программиста, для открытия новых способов взаимодействия с информацией и, как эксистенциальная цель (сверх-цель), для открытия новой супер-информации и продвижения человечества на шаг вперед по лестнице прогресса...
И, как обычно, делаем это в форме описания тулинга для мини-фреймворка core-kbt, с обычной стандартной целью - получить полезный фидбек, провести синхронизацию рассматриваемых подходов с текущими используемыми (современными, популярными) подходами, определить текущие потребности и определить ниши для данного фреймворка. В конце опишем туториал как пользоваться базовыми темплейтами для Obsidian Templater для развития текущих "знаний".
И тут пара напоминалок.
Что такое мини-фреймворк core-kbt
Мотивация для проекта
Сформулируем текущую общую проблематику и мотивацию для проекта в форме тезисов:
Описание: LLM обучаются на естественном языке
Проблема и что можно сделать: для программирования естественный язык крайне неудобен, поэтому нужен "инструментарий", который будет условно транслировать требования задачи в полу-естественный язык так, чтобы (а) LLM однозначно "понимала" задачу в точности, (б) LLM возвращала ответ в ожидаемом виде.
Что сейчас есть в core-kbt:
AI-функции, для точной передачи задачи в LLM и получения ответа в заданной гибкой структуре
для Obsidian: точное расширяемое управление генерацией через аспекты, задаваемые в Templater темплейте
Описание: Текущие LLM ограничены: (а) в количестве своих внутренних вычислений, (б) в размере "памяти" для выполнения своих "алгоритмов", (в) в своей неустойчивости качества алгоритмов при разных характеристиках входных данных, (г) из-за особенностей и артефактов, которые есть в обучаемой выборке, и как результат, (д) в отсутствии каких либо логических гарантий на результат. С самого своего появления и до настоящего момента LLM - это машина, которая что-то принимает на вход и что-то выдает на выводе, причем про значение на выходе известно лишь то, что оно будет максимально полезно (при этом заданном входе). Эти ограничения в основном сейчас неконтролируемы. Отметим, что метод in-context prompting (предоставление всей необходимой информации для ответа модели в контексте) уменьшает количество галлюцинаций LLM модели и улучшает логическую консистентность, но не дает гарантий в явном виде.
Примечание: Стоит отметить, что указанные выше ограничения LLM являются качественными ограничениями на уровне архитектуры и они не будут решены в новых версиях LLM и при увеличении количества параметров. Поэтому обозначенные проблемы нуждаются в разработке принципиальных решений.
Проблема и что можно сделать: для программирования нужны гарантии. Для любого технического инструмента нужны гарантии. Нужен "инструментарий" с такими свойствами:
декомпозиция задачи на максимально мелкие элементарные задачи + вычисление элементарных задач + обратный синтез в конечный ответ. Для синтеза нужна архитектура вычислений и оптимизации более высокого уровня
поиск и предоставление LLM необходимого оптимального контекста
контроль ответов от LLM: пост-тестирование, проверка логической корректности, проверка фактологической корректности
Что сейчас есть в core-kbt:
выявление и описание элементарных задач в виде AI-функции
предоставление LLM необходимого контекста через базу знаний
elementary
Что планируется в core-kbt:
архитектура вычислений на основе агентов
методы оптимизации базы
elementaryдля задачи через "траектории" ("ktb" - "knowledge base trajectory"), т.е. варианты баз знаний для дальнейшего выбора лучшей "траектории" через процедуру оптимизацииинтеграция с фреймворками для тестирования и мониторинга (Langfuse и др.)
интеграция с IDE для развития знаний
проверка логической корректности
проверка фактологической корректности
Описание: Для профессионального использования LLM недостаточно просто общаться с чат ботом. К тому же, как правило, текущие "знания" нужно как-то сохранять для их дальнейшего использования и улучшения.
Проблема и что можно сделать: для специального использования нужны специальные инструменты и IDE.
Что сейчас есть в core-kbt:
для Obsidian: скрипты и темплейты, для интеграции функционала core-kbt
Концепция проекта
Проект core-kbt (kbt — Knowledge Base Trajectory) — это мини-фреймворк на Python для разработки приложений на основе больших языковых моделей (LLM). Его основной принцип — подход с управляемой Базой Знаний (elementary), где ИИ-агенты в будущем будут использовать и интеллектуально развивать базу знаний (elementary) с контролем версий для выполнения сложных задач.
ИИ-функции (AI-функции)
ИИ-функции — это инструменты, которые ИИ-агенты используют для взаимодействия с миром и модификации Базы Знаний (elementary). Они спроектированы как повторно используемые, модульные и "интеллектуальные" компоненты с четко определенными схемами ввода и вывода.
Существует два способа реализации ИИ-Функции:
Шаблон Jinja2: Шаблон промпта, который может быть выполнен LLM.
Модуль Python: Функция Python, которая может содержать произвольную логику, включая вызовы внешних API или другие сложные операции.
Сервер Flask предоставляет эти функции через RESTful API, с динамической компиляцией, обрабатывая авторизацию и диспетчеризацию. Это обеспечивает широкую возможность интеграцию ИИ-Функции с другими системами, например:
браузерными плагинами (chatGPTBox)
n8n-нодами
плагинами для работы с базами знаний, например, с Obsidian
другими высоко-уровневыми приложениями на любом языке программирования.
База знаний (elementary)
База знаний elementary — это структурированное хранилище доменных знаний, которые с которым работают агенты. Она хранится в виде иерархии файлов YAML, JSON или Turtle, что делает ее одновременно читаемой человеком и обрабатываемой машиной.
Вся БЗ хранится в Git, что обеспечивает надежное версионирование. Каждая ветка может представлять различное состояние знаний, что позволяет проводить эксперименты и проводить анализ работы агентов.
ИИ-агенты
ИИ-агенты — центральные действующие лица в системе. Их основная роль заключается в выполнении задач путем интеллектуального изменения Базы Знаний. Каждое значимое изменение, внесенное агентом, приводит к новому, качественно иному состоянию Базы Знаний (БЗ), которое версионируется в отдельной ветке Git. Это позволяет создавать и оценивать "траекторию" состояний знаний.
В текущий момент архитектура и реализация агентской подсистемы находится в проработке.
До реализации агентской подсистемы необходимо продумать: (а) эффективную систему "элементарных" задач и запросов и (б) эффективные методы работы с базами знаний.
Тулинг для core-kbt
Перейдем к описанию текущего тулинга для core-kbt. Такой тулинг уже выглядит полезным несмотря на то, что агентская система еще не реализована и эффективные методы работы с базами знаний еще окончательно не сформулированы.
Начало работы c core-kbt
Клонируем репозиторий:
git clone https://github.com/ady1981/core-kbt.git
cd core-kbt
Задаем значения переменных среды в
.envфайле, например для DeepSeek:
HOST=0.0.0.0
PORT=5001
OPENAI_BASE_URL=https://api.deepseek.com
OPENAI_MODEL=deepseek-chat
OPENAI_API_KEY=<DEEPSEEK_API_TOKEN>
AI_FUNC_API_TOKEN=<A_SECRET>
Запускаем сервер AI-функций:
через docker:
./run-gh-docker-image.sh
через командную строку:
./runner.sh -s kbt-core/ai_function_server.py
Допустим мы хотим узнать столицу России. Будем использовать готовую AI-функцию
generate. Вызываем AI-функцию с соответствующими входными параметрами (target_specification):
source .env
curl -X PUT "http://127.0.0.1:5001/ai-func/generate" \ -H "Api-Token: $AI_FUNC_API_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d "{ \"target_specification\": \"target_description: What is Capital of Russia?\"}"
Ответ:
{
"result": {
"items": [
{
"item": "Moscow",
"reasoning": "The target question asks for the capital of Russia. Based on general knowledge, the capital of Russia is Moscow."
}
],
"other_notes": "The information retrieval strategy specified no external context knowledge, relying solely on general knowledge to answer the factual question about the capital of Russia."
}
}
Универсальный темплейт для промпта
Понятно, что центральной темой для эффективного использования LLM является промпт-инжиниринг, т.е. подходы к построению эффективных запросов для получения нужных ответов.
Как известно, LLM всегда решает только одну задачу - generatively-continue-prompt. Можно записать общее представление с выделением различных частей для промпта так:
LLM_prompt:
prompt_structure_and_notation_self_specification: []
target_specification:
- task_specification
- target_semantic_specification
information_retrieval_strategy:
- context_knowledge_specification:
- context_knowledge_topic
- context_knowledge_source:
- properties
- content
- knowledge_sources_selection_strategy
- context_preparation_strategy
- contextual_alignment_strategy
- contextual_memory_strategy
- ...
output_generation_strategy:
- execution_plan_specification
- task_decomposition_specification
- knowledge_consolidation_specification
- evaluation_metrics
- iteration_and_refinement_strategy
- examples
- safety_and_ethics_specification
- post_generation_verification_specification
- ...
output_specification:
- structure_and_formatting_specification
- output_constrains_specification
- output_content_strategy
- ...
Смысл этих частей промпта более-менее ясен из названия. Дополнительно отметим следующее:
любая specification - задает спецификацию, т.е. однозначно понятные требования
любая strategy - задает набор политик, как лучше достичь желаемого результата
если task_specification задать сложно, то можно задать task_description. В дальнейшем результат генерации с таким промптом можно сравнить с результатов генерации для промпта с заданными соответствующим task_specification
target_specification - задает спецификацию "смысла" запроса и результата
information_retrieval_strategy - задает как найти информацию для решения запроса
output_generation_strategy - задает стратегию, как генерировать ответ, чтобы прийти к нужному результату.
Приведем пример для summarize-промпта в этом представлении:
LLM_prompt:
target_specification:
- task_specification: Abstractive summarize
- target_semantic_specification: Concise
information_retrieval_strategy:
- context_knowledge_specification:
- context_knowledge_source: |
{{TO_SUMMARIZE_TEXT}}
- knowledge_sources_selection_strategy: Use only the provided input text.
- contextual_alignment_strategy: Ensure summary reflects the core meaning of the input.
output_generation_strategy:
- focus_on: the central theme
- execution_plan_specification: Read input, identify key sentences/concepts, synthesize into a short paragraph.
- task_decomposition_specification: Single step.
- knowledge_consolidation_specification: Extract and combine main ideas.
- evaluation_metrics: Conciseness, Fidelity to source.
- safety_and_ethics_specification: Maintain factual accuracy.
- post_generation_verification_specification: Check if summary is significantly shorter than the original.
output_specification:
- structure_and_formatting_specification: Plain text paragraph.
- output_constrains_specification: Maximum 3 sentences.
Отметим, что существование эффективного универсального темплейта для LLM промпта означает, что можно сделать одну условно универсальную AI-функцию, через которую можно задать для LLM любую задачу. Причем настраивать LLM промпты можно по некоторой универсальной системе аспектов. Однако, для большего удобства и повышения эффективности LLM промптов для выделенных задач имеет смысл создавать отдельные AI-функции, в которых можно более конкретно определять входные поля и, что еще более важно, в выходной JSON-Schema определять более конкретные выходные поля (в том чи��ле для того, чтобы "заставить" модель "подумать" над генерируемыми значениями).
Идеи для управления промптами
Следующий вопрос состоит в том, как представлять эти части промптов. Предложим набор идей:
для максимальной эффективности мы хотим прийти к определенной универсальной системе управления промптом. К такой системе, чтобы для любой задачи нужно было итеративно прийти к максимально эффективному промпту. Для этого все базовые элементы спецификации мы будем представлять в виде block-level Markdown свойств в виде:
[ <aspect_name>.<feature_name>:: <feature_value> ]
(или просто как <aspect_name>.<feature_name>: <feature_value>, если это не создает трудности парсинга).
в core-kbt структурный формат в
output_specificationуже выбран - это JSON Schema, которая подставляется "��од капотом". Поэтому вoutput_specificationмы будем определять другие аспекты формата ответа.
Вариант базовых Templater темплейтов для развития "знаний" в Obsidian
Выберем самый простой вариант эффективной генерации новой информацию в Obsidian: пользователь, работая в определенном .md документе, в редакторе выделяет текст, к которому применяет определенный Templater темплейт, которому соответствует определенным образом настроенная AI-функция. AI-функция выполняется и результат вставляется в текущий документ сразу после выбранного текста (для дальнейшего редактирования или новой генерации).
В таком сценарии для AI-функции можно использовать такие элемента входных данных:
выделенный текст, к которому нужно применить AI-функцию
название файла, которое задает "тему" области знаний, в которой требуется генерация
полное содержание текущего файла
значения аспектов для заданной задачи, определенные в коде Templater темплейта. Выбирая нужную информацию и генерируя новую информация через настраиваемые темплейты генерации можно развивать "знания", описываемые в текущем документе.
Отметим также, что если для .md документа настроить и использовать определенную систему inline (block level) атрибутов, подходящих для автоматической обработки, то это превращает документ в полноценную базу знаний. Базами знаний такого типа можно управлять через Obsidian + Dataview плагин или другими инструментами.
Предложим следующий набор базовых темплейтов для развития "знаний" в Obsidian.
Базовые темплейты для item
Эти темплейты применяются к выбранному тексту, который рассматривается как единичный элемент (item). Для генерации используются только внутренние знания.
темплейт | Описание | Входные данные | Тип результата |
|---|---|---|---|
factual_qa | темплейт для ответа на фактологческий вопрос | Вопрос | List |
term_identify | темплейт для определения термина по описанию или определению. Обратная функция к функции генерации определения для термина | Описание для термина | AnyMarkdown |
example | темплейт для генерации примеров для заданного описания | Группа, категория или описание | List |
review | темплейт для генерации review-документа | Текст или код | AnyMarkdown |
summarize | темплейт для генерации summary-документа | Текст | AnyMarkdown |
aspected_analyze | темплейт для анализа текста через значения аспектов | Текст или код | PropertyList |
aspected_rewrite | темплейт для редактирования текста через значения аспектов | Текст или код | WithPropertyMarkdown |
Все темплейты можно и нужно кастомизировать для более точного решения конкретной задачи.
Также можно создавать новые темплейты на основе базовых для новых более узких задач.
Тип результата здесь описан для общего понимания и что означает этот тип подразумевается в названии.
Базовые темплейты для items
Эти темплейты применяются к выбранному тексту как к последовательности элементов (items).
темплейт | Описание | Входные данные | Тип результата |
|---|---|---|---|
difference | темплейт для генерации различающихся аспектов для двух элементов | Элементы для сравнения (по умолчанию, элементы должны быть заданы на отдельной строчке) | DifferenceMarkdown |
common | темплейт для генерации общих аспектов для двух элементов | Элементы для сравнения (по умолчанию, элементы должны быть заданы на отдельной строчке) | PropertyList |
new_item | темплейт для генерации новых элементов для заданной последовательности | Элементы | List |
group | темплейт для генерации названия группы (или категории) для заданной последовательности | Элементы | AnyMarkdown |
Базовые темплейты для context + item
Этот темплейт применяется к выбранному тексту и для генерации используется информация из текущего активного документа. Текст вопроса следует вводить в самом конце активного документа.
темплейт | Описание | Входные данные | Тип результата |
|---|---|---|---|
incontext_qa | темплейт для генерации ответов на вопрос по текущему документу | 1. Текст документа. 2. Вопрос по тексту документа | List |
Пример установки и использования
Установка
установить Obsidian и Templater-плагин
установить, настроить env-параметры и запустить сервер AI-функций (например, через docker)
настроить obsidian-templater-core-kbt для Obsidian Templater:
скачать репозиторий obsidian-templater-core-kbt в папку. Обозначим путь к этой папке как OBS_CORE_KBT.
обозначим директорию с рабочим Obsidian vault как KNOWLEDGE
для настройки теймплетов нужно:
скопировать содержимое папки
$OBS_CORE_KBT/srcв папку$KNOWLEDGE/_scripts(или создать ссылку)скопировать содержимое папки
$OBS_CORE_KBT/templatesв папку$KNOWLEDGE/_templates(или создать ссылку)в конфиге плагина Templater в Obsidian: в значении
User script functions / script files folder locationуказать_scriptsв конфиге плагина Templater в Obsidian: в значении
Template folder locationуказать_templates
Примеры использования
factual_qa
создать новый документ в Obsidian vault -
geography.mdв документе написать вопрос: "Столица России"
выделить текст
вызвать кастомный темплейт через команду в Obsidian:
Templater: Open insert template modal → factual_qa. После вычисления темплейта в активный документ вставится результат генерации:
Столица России
- Столицей России является Москва.
- [reference.1:: Общеизвестный географический факт // internal knowledge]
difference
создать новый документ в Obsidian vault -
earth science.mdв документе написать элементы для сравнения:
Weather
Climate
выделить эти элементы для сравнения
вызвать difference Templater темплейт. После вычисления темплейта в активный документ вставится результат генерации:
# Difference
## Weather
- [**Временной масштаб.Продолжительность описания**:: Краткосрочныи (часы, дни, недели)]
- [Предмет описания.Фокус описания:: Конкретные, мгновенные атмосферные условия]
- [Изменчивость.Степень изменчивости:: Высокая (частые и резкие изменения)]
## Climate
- [**Временной масштаб.Продолжительность описания**:: Долгосрочныи (месяцы, годы, десятилетия)]
- [Предмет описания.Фокус описания:: Статистические характеристики атмосферных условии]
- [Изменчивость.Степень изменчивости:: Низкая (стабильные тенденции)]
common
создать новый документ в Obsidian vault -
cars.mdв документе написать текст для сравнения:
Haval Dargo
Haval H3
выделить этот текст и вызвать common Templater темплейт. После вычисления темплейта в активный документ вставится результат генерации:
- [**Платформа и шасси.Платформа**:: Общая модульная платформа Haval (предположительно)]
- [**Силовая установка.Тип двигателя**:: Бензиновый турбированный двигатель]
- [**Силовая установка.Тип трансмиссии**:: Автоматическая (вероятно, DCT)]
- [Дизайн экстерьера.Фирменный стиль решетки радиатора:: Наличие крупной, доминирующей решетки радиатора]
review
создать новый документ в Obsidian vault -
history.mdв документе написать текст для ревью:
Основной причиной распада Западной Римской империи в 476 году нашей эры стало подавляющее военное превосходство гуннов, которые в одиночку разграбили Рим и возвели на престол Одоакра.
выделить этот текст и вызвать review Templater темплейт. После вычисления темплейта в активный документ вставится результат генерации:
# Review
### Оценка: Критическая неточность в определении основной причины распада
**Анализ:** Утверждение, что основной причиной распада Западной Римской империи в 476 году стало «подавляющее военное превосходство гуннов, которые в одиночку разграбили Рим и возвели на престол Одоакра», является исторически некорректным и чрезмерно упрощенным...
**Рекомендация:** Необходимо переформулировать причину, признав, что гунны (особенно под предводительством Аттилы) были мощным дестабилизирующим фактором, но не единственной и не прямой причиной краха 476 года...
### Анализ: Смешение причинно-следственных связей и хронологии
**Слабость:** Текст ошибочно связывает «разграбление Рима» (которое происходило в разные периоды, например, вестготами в 410 г. и вандалами в 455 г.) и возведение Одоакра на престол (476 г.) как прямые и единовременные следствия мощи гуннов. Гунны были разгромлены в битве на Каталаунских полях (451 г.) и их влияние резко снизилось после смерти Аттилы (453 г.), задолго до 476 года.
**Рекомендация:** Разделить факторы: 1) Внешнее давление (включая гуннов и последующие миграции); 2) Внутренний распад административной и военной структуры; 3) Событие 476 года как политический финал, а не военное завоевание.
### Оценка: Недостаточная детализация ключевых событий
**Анализ:** Фраза «разграбили Рим» неточна в контексте 476 года...
**Действенное предложение:** Для повышения экспертного уровня контента необходимо заменить обобщение на конкретику: «...привело к окончательному распаду имперской власти на Западе, кульминацией которого стало смещение последнего императора, Ромула Августула, германским вождем Одоакром в 476 году».
aspected_rewrite
создать новый документ в Obsidian vault -
history.mdв документе написать текст для модификации:
Основной причиной распада Западной Римской империи в 476 году нашей эры стало подавляющее военное превосходство гуннов, которые в одиночку разграбили Рим и возвели на престол Одоакра.
выделить этот текст и вызвать aspected_rewrite Templater темплейт. После вычисления темплейта в активный документ вставится результат генерации:
Ключевым фактором, завершившим существование Западной Римской империи в 476 году н.э., стало совокупное воздействие внутренних системных кризисов и перманентного миграционного давления германских федератов, кульминацией чего стало смещение Ромула Августула Одоакром.
- [Expertness_level.level:: High]
- [Causality_description.accuracy:: Complex systemic failure and external pressure]
new_item
создать новый документ в Obsidian vault -
general sense.mdв документе написать элементы:
- Пятница
- Суббота
- Воскресенье
- Понедельник
выделить этот текст и вызвать new_item Templater темплейт. После вычисления темплейта в активный документ вставится результат генерации:
- Вторник
- Среда
- Четверг
group
Создать документ в Obsidian vault -
general sense.mdв документе написать элементы:
- Пятница
- Суббота
- Воскресенье
- Понедельник
- Вторник
- Среда
- Четверг
выделить этот текст и вызвать group Templater темплейт. После вычисления темплейта в активный документ вставится результат генерации:
Дни недели
Резюме
В резюме перечислим, что можно было узнать в этой статье:
текущий статус мини-фреймворка core-kbt
универсальный темплейт для промпта и идею разработки эффективного промпта через систему аспектов
вариант базовых Templater темплейтов для развития "знаний" в Obsidian
туториал как настроить и использовать базовые темплейты в Obsidian
Или по другому:
Работа с .md документами с целью развития знания с помощью LLM
Без помощи obsidian-templater-core-kbt и других фреймворков ❌ | С помощью obsidian-templater-core-kbt ✅ |
|---|---|
нужно составить эффективный prompt для конкретной задачи. Как его составить? | нужно выбрать темплейт для конкретной задачи из списка и настроить значения требуемых аспектов. Если для задачи нет темплейта, то его просто сделать через копирование. Выходной результат также просто настраивается |
как убедится, что текущий prompt максимально эффективен для конкретной задачи? Что нужно улучшать в промпте? | можно улучшать результат через систему аспектов |
как вставить в текущий документ ответы на некоторой фактологический вопрос? | использовать темплейт factual_qa |
как определить какой термин подходит под выбранное описание? | использовать темплейт term_identify |
как найти примеры для выбранного элемента? 🔝 | использовать темплейт example |
как составить экспертное ревью для выбранного текста? 🔝🔝 | использовать темплейт review |
как составить краткое изложение для выбранного текста? | использовать темплейт summarize |
как составить аспектный анализ для выбранного текста? 🔝 | использовать темплейт aspected_analyze |
как переписать выбранный текст, контролируя аспекты текста? 🔝🔝 | использовать темплейт aspected_rewrite |
как определить в каких аспектах различаются выбранные элементы? 🔝🔝 | использовать темплейт difference |
как выбрать лучшее их двух? 🔝🔝 | через темплейт difference сделать аспектное сравнения для нужных аспектов |
как определить в каких аспектах совпадают выбранные элементы? 🔝🔝 | использовать темплейт common |
как найти новый элемент множества для выбранной последовательности элементов? 🔝🔝 | использовать темплейт new_item |
как найти название группы, которая объединяет выбранную последовательность элементов? 🔝 | использовать темплейт group |
как получить ответы на выбранный вопрос по текущему документу? | использовать темплейт incontext_qa |
как сгенерировать новые идеи для развития концепции? 🔝🔝 | 1. использовать темплейт new_item для текущего набора идей. 2. сделать аспектный анализ текущих идей через темплейт aspected_analyze, определить, какие аспекты можно улучшить и сгенерировать новую идею через aspected_rewrite. 3... |
Ждем продолжения в следующих сериях.. .
