Продолжаем исследовать возможности технологии LLM для повышения эффективности работы человека-пользователя и работы человека-программиста, для открытия новых способов взаимодействия с информацией и, как эксистенциальная цель (сверх-цель), для открытия новой супер-информации и продвижения человечества на шаг вперед по лестнице прогресса...
И, как обычно, делаем это в форме описания тулинга для мини-фреймворка core-kbt, с обычной стандартной целью - получить полезный фидбек, провести синхронизацию рассматриваемых подходов с текущими используемыми (современными, популярными) подходами, определить текущие потребности и определить ниши для данного фреймворка. В конце опишем туториал как пользоваться базовыми теймплейтами для Obsidian Templater для развития текущих "знаний".
И тут пара напоминалок.
Сформулируем текущую общую проблематику и мотивацию для проекта в форме тезисов:
Описание: 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) с контролем версий для выполнения сложных задач.
ИИ-функции — это инструменты, которые ИИ-агенты используют для взаимодействия с миром и модификации Базы Знаний (elementary). Они спроектированы как повторно используемые, модульные и "интеллектуальные" компоненты с четко определенными схемами ввода и вывода.
Существует два способа реализации ИИ-Функции:
Шаблон Jinja2: Шаблон промпта, который может быть выполнен LLM.
Модуль Python: Функция Python, которая может содержать произвольную логику, включая вызовы внешних API или другие сложные операции.
Сервер Flask предоставляет эти функции через RESTful API, с динамической компиляцией, обрабатывая авторизацию и диспетчеризацию. Это обеспечивает широкую возможность интеграцию ИИ-Функции с другими системами, например:
браузерными плагинами (chatGPTBox)
n8n-нодами
плагинами для работы с базами знаний, например, с Obsidian
другими высоко-уровневыми приложениями на любом языке программирования.
База знаний elementary — это структурированное хранилище доменных знаний, которые с которым работают агенты. Она хранится в виде иерархии файлов YAML, JSON или Turtle, что делает ее одновременно читаемой человеком и обрабатываемой машиной.
Вся БЗ хранится в Git, что обеспечивает надежное версионирование. Каждая ветка может представлять различное состояние знаний, что позволяет проводить эксперименты и проводить анализ работы агентов.
ИИ-агенты — центральные действующие лица в системе. Их основная роль заключается в выполнении задач путем интеллектуального изменения Базы Знаний. Каждое значимое изменение, внесенное агентом, приводит к новому, качественно иному состоянию Базы Знаний (БЗ), которое версионируется в отдельной ветке Git. Это позволяет создавать и оценивать "траекторию" состояний знаний.
В текущий момент архитектура и реализация агентской подсистемы находится в проработке.
До реализации агентской подсистемы необходимо продумать: (а) эффективную систему "элементарных" задач и запросов и (б) эффективные методы работы с базами знаний.
Перейдем к описанию текущего тулинга для 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 мы будем определять другие аспекты формата ответа.
Выберем самый простой вариант эффективной генерации новой информацию в Obsidian: пользователь, работая в определенном .md документе, в редакторе выделяет текст, к которому применяет определенный Templater теймплейт, которому соответствует определенным образом настроенная AI-функция. AI-функция выполняется и результат вставляется в текущий документ сразу после выбранного текста (для дальнейшего редактирования или новой генерации).
В таком сценарии для AI-функции можно использовать такие элемента входных данных:
выделенный текст, к которому нужно применить AI-функцию
название файла, которое задает "тему" области знаний, в которой требуется генерация
полное содержание текущего файла
значения аспектов для заданной задачи, определенные в коде Templater теймплейта. Выбирая нужную информацию и генерируя новую информация через настраиваемые теймплейты генерации можно развивать "знания", описываемые в текущем документе.
Отметим также, что если для .md документа настроить и использовать определенную систему inline (block level) атрибутов, подходящих для автоматической обработки, то это превращает документ в полноценную базу знаний. Базами знаний такого типа можно управлять через Obsidian + Dataview плагин или другими инструментами.
Предложим следующий набор базовых теймплейтов для развития "знаний" в Obsidian.
Эти теймплейты применяются к выбранному тексту, который рассматривается как единичный элемент (item). Для генерации используются только внутренние знания.
|
Теймплейт |
Описание |
Входные данные |
Тип результата |
|---|---|---|---|
|
factual_qa |
Теймплейт для ответа на фактологческий вопрос |
Вопрос |
List |
|
term_identify |
Теймплейт для определения термина по описанию или определению. Обратная функция к функции генерации определения для термина |
Описание для термина |
AnyMarkdown |
|
example |
Теймплейт для генерации примеров для заданного описания |
Группа, категория или описание |
List |
|
review |
Теймплейт для генерации review-документа |
Текст или код |
AnyMarkdown |
|
summarize |
Теймплейт для генерации summary-документа |
Текст |
AnyMarkdown |
|
aspected_analyze |
Теймплейт для анализа текста через значения аспектов |
Текст или код |
PropertyList |
|
aspected_rewrite |
Теймплейт для редактирования текста через значения аспектов |
Текст или код |
WithPropertyMarkdown |
Все теймплейты можно и нужно кастомизировать для более точного решения конкретной задачи.
Также можно создавать новые теймплейты на основе базовых для новых более узких задач.
Тип результата здесь описан для общего понимания и что означает этот тип подразумевается в названии.
Эти теймплейты применяются к выбранному тексту как к последовательности элементов (items).
|
Теймплейт |
Описание |
Входные данные |
Тип результата |
|---|---|---|---|
|
difference |
Теймплейт для генерации различающихся аспектов для двух элементов |
Элементы для сравнения (по умолчанию, элементы должны быть заданы на отдельной строчке) |
DifferenceMarkdown |
|
common |
Теймплейт для генерации общих аспектов для двух элементов |
Элементы для сравнения (по умолчанию, элементы должны быть заданы на отдельной строчке) |
PropertyList |
|
new_item |
Теймплейт для генерации новых элементов для заданной последовательности |
Элементы |
List |
|
group |
Теймплейт для генерации названия группы (или категории) для заданной последовательности |
Элементы |
AnyMarkdown |
Этот теймплейт применяется к выбранному тексту и для генерации используется информация из текущего активного документа. Текст вопроса следует вводить в самом конце активного документа.
|
Теймплейт |
Описание |
Входные данные |
Тип результата |
|---|---|---|---|
|
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
создать новый документ в Obsidian vault - geography.md
в документе написать вопрос: "Столица России"
выделить текст
вызвать кастомный теймплейт через команду в Obsidian: Templater: Open insert template modal → factual_qa. После вычисления теймплейта в активный документ вставится результат генерации:
Столица России - Столицей России является Москва. - [reference.1:: Общеизвестный географический факт // internal knowledge]
создать новый документ в Obsidian vault - earth science.md
в документе написать элементы для сравнения:
Weather Climate
выделить эти элементы для сравнения
вызвать difference Templater теймплейт. После вычисления теймплейта в активный документ вставится результат генерации:
# Difference ## Weather - [**Временной масштаб.Продолжительность описания**:: Краткосрочныи (часы, дни, недели)] - [Предмет описания.Фокус описания:: Конкретные, мгновенные атмосферные условия] - [Изменчивость.Степень изменчивости:: Высокая (частые и резкие изменения)] ## Climate - [**Временной масштаб.Продолжительность описания**:: Долгосрочныи (месяцы, годы, десятилетия)] - [Предмет описания.Фокус описания:: Статистические характеристики атмосферных условии] - [Изменчивость.Степень изменчивости:: Низкая (стабильные тенденции)]
создать новый документ в Obsidian vault - cars.md
в документе написать текст для сравнения:
Haval Dargo Haval H3
выделить этот текст и вызвать common Templater теймплейт. После вычисления теймплейта в активный документ вставится результат генерации:
- [**Платформа и шасси.Платформа**:: Общая модульная платформа Haval (предположительно)] - [**Силовая установка.Тип двигателя**:: Бензиновый турбированный двигатель] - [**Силовая установка.Тип трансмиссии**:: Автоматическая (вероятно, DCT)] - [Дизайн экстерьера.Фирменный стиль решетки радиатора:: Наличие крупной, доминирующей решетки радиатора]
создать новый документ в Obsidian vault - history.md
в документе написать текст для ревью:
Основной причиной распада Западной Римской империи в 476 году нашей эры стало подавляющее военное превосходство гуннов, которые в одиночку разграбили Рим и возвели на престол Одоакра.
выделить этот текст и вызвать review Templater теймплейт. После вычисления теймплейта в активный документ вставится результат генерации:
# Review ### Оценка: Критическая неточность в определении основной причины распада **Анализ:** Утверждение, что основной причиной распада Западной Римской империи в 476 году стало «подавляющее военное превосходство гуннов, которые в одиночку разграбили Рим и возвели на престол Одоакра», является исторически некорректным и чрезмерно упрощенным... **Рекомендация:** Необходимо переформулировать причину, признав, что гунны (особенно под предводительством Аттилы) были мощным дестабилизирующим фактором, но не единственной и не прямой причиной краха 476 года... ### Анализ: Смешение причинно-следственных связей и хронологии **Слабость:** Текст ошибочно связывает «разграбление Рима» (которое происходило в разные периоды, например, вестготами в 410 г. и вандалами в 455 г.) и возведение Одоакра на престол (476 г.) как прямые и единовременные следствия мощи гуннов. Гунны были разгромлены в битве на Каталаунских полях (451 г.) и их влияние резко снизилось после смерти Аттилы (453 г.), задолго до 476 года. **Рекомендация:** Разделить факторы: 1) Внешнее давление (включая гуннов и последующие миграции); 2) Внутренний распад административной и военной структуры; 3) Событие 476 года как политический финал, а не военное завоевание. ### Оценка: Недостаточная детализация ключевых событий **Анализ:** Фраза «разграбили Рим» неточна в контексте 476 года... **Действенное предложение:** Для повышения экспертного уровня контента необходимо заменить обобщение на конкретику: «...привело к окончательному распаду имперской власти на Западе, кульминацией которого стало смещение последнего императора, Ромула Августула, германским вождем Одоакром в 476 году».
создать новый документ в Obsidian vault - history.md
в документе написать текст для модификации:
Основной причиной распада Западной Римской империи в 476 году нашей эры стало подавляющее военное превосходство гуннов, которые в одиночку разграбили Рим и возвели на престол Одоакра.
выделить этот текст и вызвать aspected_rewrite Templater теймплейт. После вычисления теймплейта в активный документ вставится результат генерации:
Ключевым фактором, завершившим существование Западной Римской империи в 476 году н.э., стало совокупное воздействие внутренних системных кризисов и перманентного миграционного давления германских федератов, кульминацией чего стало смещение Ромула Августула Одоакром. - [Expertness_level.level:: High] - [Causality_description.accuracy:: Complex systemic failure and external pressure]
создать новый документ в Obsidian vault - general sense.md
в документе написать элементы:
- Пятница - Суббота - Воскресенье - Понедельник
выделить этот текст и вызвать new_item Templater теймплейт. После вычисления теймплейта в активный документ вставится результат генерации:
- Вторник - Среда - Четверг
Создать документ в Obsidian vault - general sense.md
в документе написать элементы:
- Пятница - Суббота - Воскресенье - Понедельник - Вторник - Среда - Четверг
выделить этот текст и вызвать group Templater теймплейт. После вычисления теймплейта в активный документ вставится результат генерации:
Дни недели
В резюме перечислим, что можно было узнать в этой статье:
текущий статус мини-фреймворка core-kbt
универсальный теймплейт для промпта и идею разработки эффективного промпта через систему аспектов
вариант базовых Templater теймплейтов для развития "знаний" в Obsidian
туториал как настроить и использовать базовые теймплейты в Obsidian
Или по другому:
|
Без помощи 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... |
Ждем продолжения в следующих сериях.. .
Источник


