Files
obsidian-vault/personal/tech/hermes-agent-improvements.md
T

132 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Hermes Agent — вынос хардкода промптов в файлы (prompt_overrides)
**Дата:** 2026-09-15
**Статус:** реализовано, закоммичено и запушено
**Репо:** `~/.hermes/hermes-agent` (сабмодуль, форк `mallexxx/hermes-agent`)
## Проблема
Стабильный слой system prompt был **захардкожен** в `agent/prompt_builder.py`.
Чтобы поменять формулировку любого блока (например, ужесточить инструкции
про язык ответа или про завершение задачи) — надо было править Python-код
сабмодуля. Это значит: правка живёт в форке, конфликтует при подтяжке
апстрима, и её надо переносить при каждом обновлении.
## Решение: prompt_overrides
Каждый хардкод-блок stable-слоя читается из `.md` файла. Маппинг — в конфиге.
Файла нет → fallback на хардкод, ничего не ломается.
### Реализация (3 файла)
**1. `agent/system_prompt.py`** — новая функция:
```python
def _load_prompt_block(agent, block_name: str, default: str) -> str:
"""Load a prompt block from a file if configured, else return default."""
overrides = getattr(agent, "_prompt_overrides", None) or {}
path = overrides.get(block_name)
if path:
try:
resolved = os.path.expanduser(path)
content = Path(resolved).read_text(encoding="utf-8").strip()
if content:
return content
except Exception:
logger.debug("Could not load prompt override '%s' from %s", block_name, path)
return default
```
7 констант заменены на её вызовы:
| Блок | Константа (fallback) |
|------|---------------------|
| `hermes_help` | `HERMES_AGENT_HELP_GUIDANCE` |
| `task_completion` | `TASK_COMPLETION_GUIDANCE` |
| `memory_guidance` | `MEMORY_GUIDANCE` |
| `session_search_guidance` | `SESSION_SEARCH_GUIDANCE` |
| `skills_guidance` | `SKILLS_GUIDANCE` |
| `tool_use_enforcement` | `TOOL_USE_ENFORCEMENT_GUIDANCE` |
| `execution_discipline` | `OPENAI_MODEL_EXECUTION_GUIDANCE` |
**2. `agent/agent_init.py`** — чтение конфига в `agent._prompt_overrides`
(+11 строк, в секции рядом с tool-loop guardrail config).
**3. `~/.hermes/hermes-whale/config.yaml`** — секция маппинга:
```yaml
agent:
prompt_overrides:
hermes_help: ~/.hermes/hermes-whale/review/hermes_help.md
task_completion: ~/.hermes/hermes-whale/review/task_completion.md
memory_guidance: ~/.hermes/hermes-whale/review/memory_guidance.md
session_search_guidance: ~/.hermes/hermes-whale/review/session_search_guidance.md
skills_guidance: ~/.hermes/hermes-whale/review/skills_guidance.md
tool_use_enforcement: ~/.hermes/hermes-whale/review/tool_use_enforcement.md
execution_discipline: ~/.hermes/hermes-whale/review/execution_discipline.md
```
**4. `~/.hermes/hermes-whale/review/`** — 7 новых `.md` файлов с содержимым
блоков. Раньше в этой папке лежали только `memory_prompt.md` и `skill_prompt.md`.
## Pitfall: prompt_overrides — это про Python-код, а не про config
Файлы `review/*.md` **обязаны быть закоммичены**. Если закоммитить `config.yaml`
с путями, но не сами файлы — подмены промпта молча исчезнут (fallback на
хардкод), потому что `_load_prompt_block` ловит отсутствие файла в `except`
и отдаёт default. Ошибки нет, поведение просто возвращается к хардкоду.
Это ровно то, что чуть не произошло: 7 файлов `review/*.md` были untracked.
## Pitfall: порядок коммита сабмодуля
Правки Python живут в сабмодуле. Порядок:
```bash
cd ~/.hermes/hermes-agent && git add agent/*.py && git commit -m "..."
cd ~/.hermes && git add hermes-agent && git commit -m "..." # обновить пин
```
Если пин не обновить — в родительском репо видно
`hermes-agent (new commits, modified content)`, и `-dirty` в diff сабмодуля.
## Коммиты и push (2026-09-15)
| Репо | Коммит | Что |
|------|--------|-----|
| `hermes-agent` | `207a1de16` | feat: load stable system-prompt blocks from config prompt_overrides |
| `~/.hermes` | `7fd200c` | feat: wire prompt_overrides + whale-thread-guard multi-bot routing |
| `~/.hermes` | `7893c35` | chore: sync skills — curator consolidation |
| `~/.hermes` | `bdf84da` | chore(lsp): add vue/dockerfile/pyright/yaml language servers |
| `~/.hermes` | `176ce9c` | chore: thread-scoped memory store + claude token refresh script |
| `~/.hermes` | `9b111fc` | chore: untrack lsp/node_modules (1957 files, 43M) |
**Запушено:**
- `hermes-agent``github.com:mallexxx/hermes-agent` (20 коммитов)
- `~/.hermes``git.mallexxx.duckdns.org/git_admin/eagle-hermes` (9 коммитов)
## Осталось в коде (не вынесено)
- `DEFAULT_AGENT_IDENTITY` — fallback, остаётся хардкодом
- `GOOGLE_MODEL_OPERATIONAL_GUIDANCE` — неактуально для Whale
- `COMPUTER_USE_GUIDANCE`, `KANBAN_GUIDANCE` — неактуально
- `PLATFORM_HINTS` — webhook там нет
- `build_skills_system_prompt()` — автогенерируется, файлом не заменить
## Зачем это было нужно
Два практических повода:
1. **Правки промпта без правки Python** — теперь формулировки живут в `.md`,
редактируются в vault-стиле, не конфликтуют при подтяжке апстрима.
2. **Фикс языкового дрейфа DeepSeek** — нужна жёсткая языковая инструкция
в промпте; теперь её можно добавить файлом, а не патчем кода.
См. [[deepseek-language-drift]].
## Связанное
- [[hermes-whale-system-prompt]] — полный состав system prompt (3 слоя)
- [[hermes-git-repo]] — структура репо, .gitignore, что коммитить
- [[deepseek-language-drift]] — баг с китайским выводом, повод для правок промпта
- [[hermes-fork-vs-upstream]] — расхождение с апстримом (24k коммитов)