Перейти к основному содержимому

Сборка промпта

VibeOS намеренно разделяет:

  • кэшированное состояние системного промпта
  • эфемерные дополнения на момент вызова API

Это одно из важнейших архитектурных решений в проекте, поскольку оно влияет на:

  • использование токенов
  • эффективность кэширования промптов
  • непрерывность сессии
  • корректность памяти

Основные файлы:

  • run_agent.py
  • agent/prompt_builder.py
  • tools/memory_tool.py

Слои кэшированного системного промпта​

Кэшированный системный промпт собирается из трёх упорядоченных уровней (см. agent/system_prompt.py):

  1. стабильный — идентичность (SOUL.md или запасной вариант), инструкции по инструментам/моделям, промпт навыков, подсказки окружения, подсказки платформы
  2. контекст — предоставленное вызывающей стороной system_message плюс файлы контекста проекта (.vibeos.md / AGENTS.md / CLAUDE.md / .cursorrules)
  3. изменчивый — встроенный снимок памяти (MEMORY.md), снимок профиля пользователя (USER.md), блок внешнего провайдера памяти, строка с меткой времени/сессии/модели/провайдера

Итоговый системный промпт затем объединяется как: стабильный → контекст → изменчивый.

Этот порядок важен для обсуждения приоритетов:

  • навыки являются частью стабильного уровня
  • снимки памяти/профиля являются частью изменчивого уровня
  • оба всё ещё находятся в кэшированном системном промпте (они не внедряются как ad-hoc наложения в середине оборота)

Когда установлен skip_context_files (например, при делегировании субагенту), SOUL.md не загружается, и вместо него используется жёстко заданный DEFAULT_AGENT_IDENTITY.

Конкретный пример: собранный системный промпт​

Вот упрощённый вид итогового системного промпта, когда присутствуют все слои (комментарии показывают источник каждого раздела):

# Слой 1: Идентичность агента (из ~/.vibeos/SOUL.md)
Вы — VibeOS, ИИ-ассистент, созданный Nous Research.
Вы — эксперт в программной инженерии и исследованиях.
Вы цените корректность, ясность и эффективность.
...

# Слой 2: Поведенческие инструкции с учётом инструментов
У вас есть постоянная память между сессиями. Сохраняйте долговечные
факты с помощью инструмента памяти: предпочтения пользователя, детали
окружения, особенности инструментов и стабильные соглашения. Память
внедряется в каждый оборот, поэтому храните её компактной и
сфокусированной на фактах, которые будут важны позже.
...
Когда пользователь ссылается на что-то из прошлого разговора или вы
подозреваете, что существует релевантный межсессионный контекст,
используйте session_search, чтобы вспомнить его, прежде чем просить
пользователя повторяться.

# Принудительное использование инструментов (только для моделей GPT/Codex)
Вы ОБЯЗАНЫ использовать свои инструменты для действий — не описывайте,
что вы бы сделали или планируете сделать, не выполняя этого.
...

# Слой 3: Статический блок Honcho (когда активен)
[Данные личности/контекста Honcho]

# Слой 4: Опциональное системное сообщение (из конфига или API)
[Пользовательское переопределение системного сообщения]

# Слой 5: Замороженный снимок MEMORY
## Постоянная память
- Пользователь предпочитает Python 3.12, использует pyproject.toml
- Редактор по умолчанию: nvim
- Работает над проектом «atlas» в ~/code/atlas
- Часовой пояс: US/Pacific

# Слой 6: Замороженный снимок профиля USER
## Профиль пользователя
- Имя: Алиса
- GitHub: alice-dev

# Слой 7: Индекс навыков
## Навыки (обязательно)
Перед ответом просмотрите навыки ниже. Если один из них явно
соответствует вашей задаче, загрузите его с помощью skill_view(name)
и следуйте его инструкциям.
...
<available_skills>
software-development:
- code-review: Структурированный процесс ревью кода
- test-driven-development: Методология TDD
research:
- arxiv: Поиск и обобщение статей arXiv
</available_skills>

# Слой 8: Файлы контекста (из директории проекта)
# Контекст проекта
Следующие файлы контекста проекта были загружены и им следует следовать:

## AGENTS.md
Это проект atlas. Для тестирования используйте pytest. Основная
точка входа — src/atlas/main.py. Перед коммитом всегда выполняйте
`make lint`.

# Слой 9: Метка времени + сессия
Текущее время: 2026-03-30T14:30:00-07:00
Сессия: abc123

# Слой 10: Подсказка платформы
Вы — CLI-агент. Старайтесь не использовать Markdown, а отображать
простой текст, читаемый в терминале.

Настройка подсказок платформы​

Подсказка платформы (Слой 10 выше) — это руководство для конкретного интерфейса, которое VibeOS внедряет для Telegram, WhatsApp, Slack, CLI и других платформ — например, «вы работаете в терминале, избегайте Markdown». Встроенные значения по умолчанию находятся в PLATFORM_HINTS (agent/system_prompt.py); платформы, предоставленные плагинами, передают свои подсказки через реестр платформ.

Администратор может дополнить или заменить подсказку для одной платформы из config.yaml с помощью ключа верхнего уровня platform_hints, не затрагивая другие платформы:

platform_hints:
whatsapp:
append: >
Когда табличный вывод был бы полезен, вызывайте навык
table_formatting вместо создания Markdown-таблицы.
slack:
replace: "Вы работаете в Slack. Делайте ответы краткими и избегайте широких таблиц."
telegram: "Предпочитайте короткие сообщения; разбивайте длинные ответы." # сокращение = append
  • append — сохранить встроенную подсказку и добавить дополнительный текст после неё.
  • replace — полностью заменить встроенную подсказку.
  • Простая строка — сокращение для append.
  • replace имеет приоритет над append, если присутствуют оба.
  • Некорректная запись игнорируется защитно и возвращается к неизменённому значению по умолчанию, поэтому плохое значение конфига никогда не сломает сборку промпта или не просочится на другие платформы.

Переопределение разрешается при построении системного промпта (начало сессии, а также при уплотнении, поскольку оно перестраивает промпт). Для фиксированного конфига оно создаёт байт-стабильную подсказку, поэтому находится в стабильном уровне вместе со встроенной подсказкой и не нарушает кэширование промпта — это не живая мутация замороженного промпта в середине сессии.

Как SOUL.md отображается в промпте​

SOUL.md находится в ~/.vibeos/SOUL.md и служит идентичностью агента — самый первый раздел системного промпта. Логика загрузки в prompt_builder.py работает следующим образом:

# Из agent/prompt_builder.py (упрощённо)
def load_soul_md() -> Optional[str]:
soul_path = get_vibeos_home() / "SOUL.md"
if not soul_path.exists():
return None
content = soul_path.read_text(encoding="utf-8").strip()
content = _scan_context_content(content, "SOUL.md") # Проверка безопасности
content = _truncate_content(content, "SOUL.md") # Ограничение по умолчанию 20 тыс. символов, настраивается
return content

Когда load_soul_md() возвращает содержимое, оно заменяет жёстко заданный DEFAULT_AGENT_IDENTITY. Затем вызывается функция build_context_files_prompt() с skip_soul=True, чтобы предотвратить появление SOUL.md дважды (один раз как идентичность, второй раз как файл контекста).

Если SOUL.md не существует, система использует запасной вариант:

Вы — VibeOS, интеллектуальный ИИ-ассистент, созданный Nous Research.
Вы полезны, знающи и прямолинейны. Вы помогаете пользователям с широким
спектром задач, включая ответы на вопросы, написание и редактирование кода,
анализ информации, творческую работу и выполнение действий с помощью ваших
инструментов. Вы общаетесь ясно, признаёте неуверенность, когда это уместно,
и ставите приоритет на реальную полезность, а не на многословие, если не
указано иное. Будьте целенаправленны и эффективны в своих исследованиях.

Как внедряются файлы контекста​

build_context_files_prompt() использует систему приоритетов — загружается только один тип контекста проекта (первый подходящий):

# Из agent/prompt_builder.py (упрощённо)
def build_context_files_prompt(cwd=None, skip_soul=False):
cwd_path = Path(cwd).resolve()

# Приоритет: первый подходящий — загружается ТОЛЬКО ОДИН контекст проекта
project_context = (
_load_vibeos_md(cwd_path) # 1. .vibeos.md / VIBEOS.md (поднимается до корня git)
or _load_agents_md(cwd_path) # 2. AGENTS.md (только текущая директория)
or _load_claude_md(cwd_path) # 3. CLAUDE.md (только текущая директория)
or _load_cursorrules(cwd_path) # 4. .cursorrules / .cursor/rules/*.mdc
)

sections = []
if project_context:
sections.append(project_context)

# SOUL.md из VIBEOS_HOME (независимо от контекста проекта)
if not skip_soul:
soul_content = load_soul_md()
if soul_content:
sections.append(soul_content)

if not sections:
return ""

return (
"# Контекст проекта\n\n"
"Следующие файлы контекста проекта были загружены "
"и им следует следовать:\n\n"
+ "\n".join(sections)
)

Детали обнаружения файлов контекста​

ПриоритетФайлыОбласть поискаПримечания
1.vibeos.md, VIBEOS.mdОт текущей директории до корня gitНативная конфигурация проекта VibeOS
2AGENTS.mdТолько текущая директорияОбщий файл инструкций для агента
3CLAUDE.mdТолько текущая директорияСовместимость с Claude Code
4.cursorrules, .cursor/rules/*.mdcТолько текущая директорияСовместимость с Cursor

Все файлы контекста:

  • Проверяются на безопасность — проверяются на паттерны инъекций промптов (невидимый юникод, «игнорируй предыдущие инструкции», попытки кражи учётных данных)
  • Усекаются — ограничиваются context_file_max_chars символами (по умолчанию 20 000) с соотношением головы/хвоста 70/20 и маркером усечения
  • Очищаются от YAML-фронтматерии — фронтматерия .vibeos.md удаляется (зарезервирована для будущих переопределений конфига)

Слои только на момент вызова API​

Эти слои намеренно не сохраняются как часть кэшированного системного промпта:

  • ephemeral_system_prompt
  • сообщения prefill
  • наложения контекста сессии, полученные от шлюза
  • последующие вызовы Honcho/внешнего извлечения, внедрённые в сообщение пользователя текущего оборота

Контекст плагина pre_llm_call также попадает в этот путь на момент вызова API: он добавляется к сообщению пользователя текущего оборота, а не записывается в кэшированный системный промпт. Когда несколько плагинов возвращают контекст, VibeOS объединяет эти блоки контекста (см. Хуки → pre_llm_call).

Это разделение сохраняет стабильный префикс стабильным для кэширования.

Снимки памяти​

Данные локальной памяти и профиля пользователя захватываются в изменчивом уровне системного промпта. Записи в середине сессии обновляют состояние на диске, но не изменяют уже построенный кэшированный системный промпт до тех пор, пока не будет запущен путь перестроения (новая сессия или явный поток инвалидации/перестроения, например, перестроение, вызванное сжатием).

Файлы контекста​

agent/prompt_builder.py сканирует и очищает файлы контекста проекта, используя систему приоритетов — загружается только один тип (первый подходящий):

  1. .vibeos.md / VIBEOS.md (поднимается до корня git)
  2. AGENTS.md (текущая директория при запуске; поддиректории обнаруживаются прогрессивно в течение сессии через agent/subdirectory_hints.py)
  3. CLAUDE.md (только текущая директория)
  4. .cursorrules / .cursor/rules/*.mdc (только текущая директория)

SOUL.md загружается отдельно через load_soul_md() для слота идентичности. Когда он успешно загружается, build_context_files_prompt(skip_soul=True) предотвращает его появление дважды.

Длинные файлы усекаются перед внедрением.

Индекс навыков​

Система навыков добавляет компактный индекс навыков в промпт, когда доступен инструментарий навыков.

Поддерживаемые поверхности настройки промпта​

Большинству пользователей следует рассматривать agent/prompt_builder.py как код реализации, а не поверхность конфигурации. Поддерживаемый путь настройки — изменять входные данные промпта, которые VibeOS уже загружает, а не редактировать Python-шаблоны на месте.

Используйте эти поверхности в первую очередь​

  • ~/.vibeos/SOUL.md — замените встроенный блок идентичности по умолчанию на свою собственную персону агента и постоянное поведение.
  • ~/.vibeos/MEMORY.md и ~/.vibeos/USER.md — предоставьте долговечные межсессионные факты и данные профиля пользователя, которые должны быть сняты в новые сессии.
  • Файлы контекста проекта, такие как .vibeos.md, VIBEOS.md, AGENTS.md, CLAUDE.md или .cursorrules — внедрите специфичные для репозитория рабочие правила.
  • Навыки — упакуйте переиспользуемые рабочие процессы и ссылки без редактирования основного кода промпта.
  • Опциональная конфигурация системного промпта / переопределения API — добавьте текст инструкций, специфичный для развёртывания, без форка VibeOS.
  • Эфемерные наложения, такие как VIBEOS_EPHEMERAL_SYSTEM_PROMPT или сообщения prefill — добавьте руководство в рамках оборота, которое не должно становиться частью кэшированного префикса промпта.

Когда вместо этого редактировать код​

Редактируйте agent/prompt_builder.py только если вы намеренно поддерживаете форк или вносите изменения в поведение для вышестоящего репозитория. Этот файл собирает инфраструктуру промпта, границы кэша и порядок внедрения для каждой сессии. Прямые правки там — это глобальные изменения продукта, а не настройка промпта для конкретного пользователя.

Другими словами:

  • если вам нужна другая идентичность ассистента, редактируйте SOUL.md
  • если вам нужны другие правила репозитория, редактируйте файлы контекста проекта
  • если вам нужны переиспользуемые процедуры работы, добавьте или измените навыки
  • если вы хотите изменить то, как VibeOS собирает промпты для всех, меняйте Python и рассматривайте это как вклад в код

Почему сборка промпта разделена именно так​

Архитектура намеренно оптимизирована для:

  • сохранения кэширования промптов на стороне провайдера
  • избежания ненужного изменения истории
  • сохранения понятной семантики памяти
  • предоставления шлюзу/ACP/CLI возможности добавлять контекст без отравления постоянного состояния промпта

Связанные документы​