[2026-09-15] eagle: family/how-to/truenas-infrastructure.md personal/tech/deepseek-language-drift.md personal/tech/hermes-agent-improvements.md personal/tech/hermes-fork-vs-upstream.md personal/tech/hermes-git-repo.md personal/tech/xray-reverse-tunnel-kraken-truenas.md

This commit is contained in:
Alexey Martemyanov
2026-09-15 12:48:53 +06:00
parent d750de3e53
commit 48c9c72b58
6 changed files with 549 additions and 6 deletions
+131
View File
@@ -0,0 +1,131 @@
# 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 коммитов)