[nu-demo] hero_agent prompt.rs: tool-use directive for hero_* questions needs strengthening (and reliable rebuild) #149

Closed
opened 2026-04-24 01:20:01 +00:00 by mik-tf · 1 comment
Owner

Symptom

On heronu, asking hero_agent agent.chat a plain question like "What is Hero OS and what can it do?" returns a generic "lightweight operating system for all devices" answer even when:

  • LLM is routed through hero_aibroker with Claude Haiku 4.5 as the backing model (honors tool-use hints);
  • The search_hero_docs tool is registered and, when called explicitly ("Call search_hero_docs with query=..."), returns clean grounded Q&A content describing Hero OS correctly as a "sovereign digital workspace";
  • hero_agent/src/tool_router.rs lists search_hero_docs in the default always_include (patch landed, strings hero_agent_server | grep always_include confirms).

So the tool is offered to the LLM, and Claude honors explicit instructions — but it doesn't pro-actively call search_hero_docs without an instruction. The LLM is comfortably describing from training data when the system prompt doesn't force grounding.

Two gaps

1. The system-prompt directive is too soft

hero_agent/crates/hero_agent/src/prompt.rs::build_system_prompt currently ends with a Guidelines block:

- Use tools when needed rather than guessing
- When asked about Hero OS features or architecture, use search_hero_docs first
- When asked to interact with a service, use MCP tools (list_services, then generate_code)

Claude (and any well-trained LLM) reads "when needed" and "first" as guidance, not mandate. It weighs "I already know this" against the guideline and picks "already know." For a documentation-grounded agent, we want the opposite: any question mentioning hero_* names must trigger a search_hero_docs call first, with the answer citing the doc page.

Proposed replacement (pragmatic — apply on development_mik_nu_demo, then roll into development behind tests):

- MANDATORY: For ANY question that mentions Hero, hero_os, hero_books, hero_agent, hero_aibroker, hero_router, hero_osis, hero_foundry, hero_voice, hero_proxy, or any service starting with `hero_`  you MUST call `search_hero_docs` before answering. Do not rely on training data; "Hero OS" is a specific product (sovereign digital workspace running in the browser), NOT to be confused with "Hero Vired" (an unrelated learning platform). Always cite the doc page in your reply (e.g. `(hero_os_guide, overview)`).

2. Rebuild story is fragile

The prompt.rs edit was made on heronu and the agent was restarted, but strings ~/hero/bin/hero_agent_server | grep -c MANDATORY returned 0 — the binary was NOT actually rebuilt with the change (cargo incremental compile likely skipped the crate because another file was the ultimate cargo build -p hero_agent_server root, and prompt.rs is in hero_agent lib crate).

Specifically: the binary at ~/hero/bin/hero_agent_server timestamped 00:56 was identical to a build from BEFORE the prompt.rs edit — the nu-shell install script that copied it across didn't invoke cargo build with proper dep tracking.

Action: service_agent.nu (see #135 — still missing) must:

  1. Run cargo build -p hero_agent_server --release (or debug) in the hero_agent workspace
  2. Verify the new binary picks up source changes (strings $binary | grep $unique_marker_from_src)
  3. Only THEN copy to ~/hero/bin/

Without step (2) as a guard, prompt.rs edits are silently no-op'd across rebuilds.

Verification plan (once fixed)

After rebuild + restart:

curl --unix-socket ~/hero/var/sockets/hero_agent/rpc.sock \
  -X POST http://localhost/rpc \
  -H 'Content-Type: application/json' \
  -H 'X-Hero-Context: default' \
  -d '{"jsonrpc":"2.0","id":1,"method":"agent.chat","params":{"message":"What is Hero OS?","model":"claude-haiku-4.5"}}'

Expected: response should contain sovereign digital workspace, browser-based, or explicit doc citation like (hero_os_guide, overview). Generic answers ("user-friendly OS", "lightweight") are a regression.

  • #148 — the flow-documentation index issue (references this)
  • Sibling issue: [nu-demo] hero_agent should support tool_choice="required" for grounded modes (filed separately — belt-and-suspenders for when system prompts alone aren't enough)

Signed-off-by: mik-tf

## Symptom On heronu, asking hero_agent `agent.chat` a plain question like `"What is Hero OS and what can it do?"` returns a generic "lightweight operating system for all devices" answer even when: - LLM is routed through hero_aibroker with Claude Haiku 4.5 as the backing model (honors tool-use hints); - The `search_hero_docs` tool is registered and, when called explicitly (`"Call search_hero_docs with query=..."`), returns clean grounded Q&A content describing Hero OS correctly as a "sovereign digital workspace"; - `hero_agent/src/tool_router.rs` lists `search_hero_docs` in the default `always_include` (patch landed, `strings hero_agent_server | grep always_include` confirms). So the tool *is* offered to the LLM, and Claude honors explicit instructions — but it doesn't pro-actively call `search_hero_docs` without an instruction. The LLM is comfortably describing from training data when the system prompt doesn't force grounding. ## Two gaps ### 1. The system-prompt directive is too soft `hero_agent/crates/hero_agent/src/prompt.rs::build_system_prompt` currently ends with a Guidelines block: ```rust - Use tools when needed rather than guessing - When asked about Hero OS features or architecture, use search_hero_docs first - When asked to interact with a service, use MCP tools (list_services, then generate_code) ``` Claude (and any well-trained LLM) reads "when needed" and "first" as guidance, not mandate. It weighs "I already know this" against the guideline and picks "already know." For a documentation-grounded agent, we want the opposite: _any_ question mentioning `hero_*` names must trigger a `search_hero_docs` call first, with the answer citing the doc page. **Proposed replacement** (pragmatic — apply on `development_mik_nu_demo`, then roll into `development` behind tests): ```rust - MANDATORY: For ANY question that mentions Hero, hero_os, hero_books, hero_agent, hero_aibroker, hero_router, hero_osis, hero_foundry, hero_voice, hero_proxy, or any service starting with `hero_` — you MUST call `search_hero_docs` before answering. Do not rely on training data; "Hero OS" is a specific product (sovereign digital workspace running in the browser), NOT to be confused with "Hero Vired" (an unrelated learning platform). Always cite the doc page in your reply (e.g. `(hero_os_guide, overview)`). ``` ### 2. Rebuild story is fragile The prompt.rs edit was made on heronu and the agent was restarted, but `strings ~/hero/bin/hero_agent_server | grep -c MANDATORY` returned `0` — the binary was NOT actually rebuilt with the change (cargo incremental compile likely skipped the crate because another file was the ultimate `cargo build -p hero_agent_server` root, and prompt.rs is in `hero_agent` lib crate). Specifically: the binary at `~/hero/bin/hero_agent_server` timestamped 00:56 was identical to a build from BEFORE the prompt.rs edit — the nu-shell install script that copied it across didn't invoke `cargo build` with proper dep tracking. **Action:** `service_agent.nu` (see https://forge.ourworld.tf/lhumina_code/home/issues/135 — still missing) must: 1. Run `cargo build -p hero_agent_server --release` (or debug) in the hero_agent workspace 2. Verify the new binary picks up source changes (`strings $binary | grep $unique_marker_from_src`) 3. Only THEN copy to `~/hero/bin/` Without step (2) as a guard, prompt.rs edits are silently no-op'd across rebuilds. ## Verification plan (once fixed) After rebuild + restart: ```bash curl --unix-socket ~/hero/var/sockets/hero_agent/rpc.sock \ -X POST http://localhost/rpc \ -H 'Content-Type: application/json' \ -H 'X-Hero-Context: default' \ -d '{"jsonrpc":"2.0","id":1,"method":"agent.chat","params":{"message":"What is Hero OS?","model":"claude-haiku-4.5"}}' ``` Expected: response should contain `sovereign digital workspace`, `browser-based`, or explicit doc citation like `(hero_os_guide, overview)`. Generic answers ("user-friendly OS", "lightweight") are a regression. ## Related - https://forge.ourworld.tf/lhumina_code/home/issues/148 — the flow-documentation index issue (references this) - Sibling issue: `[nu-demo] hero_agent should support tool_choice="required" for grounded modes` (filed separately — belt-and-suspenders for when system prompts alone aren't enough) Signed-off-by: mik-tf
Author
Owner

Fixed in hero_agent commit 61d702d on development.

Two soft lines in build_system_prompt() Guidelines were replaced with one explicit MANDATORY directive:

-- Use tools when needed rather than guessing
-- When asked about Hero OS features or architecture, use search_hero_docs first
+- MANDATORY GROUNDING: For ANY question that mentions Hero, hero_os,
+  hero_books, hero_agent, hero_aibroker, hero_router, hero_osis,
+  hero_foundry, hero_voice, hero_proxy, hero_browser, hero_collab,
+  hero_livekit, hero_proc, hero_skills, hero_archipelagos, or any
+  service starting with `hero_` — you MUST call `search_hero_docs`
+  BEFORE answering. Do not rely on training data: "Hero OS" is a
+  specific product (a sovereign digital workspace running in the
+  browser), NOT to be confused with "Hero Vired" (an unrelated
+  learning platform) or generic "hero" references. Always cite the
+  doc page in your reply (e.g. `(hero_os_guide, overview)`). If
+  search_hero_docs returns no results, say so explicitly rather than
+  falling back to training data.

Design choices that match the issue body's analysis:

  • Lists every hero_ service we ship* so the LLM has a concrete trigger set, not a fuzzy "about Hero OS" check.
  • MUST and BEFORE in uppercase so the directive isn't read as guidance.
  • Hero Vired disambiguation — the most common training-data confusion observed in heronu testing.
  • Citation requirement ((hero_os_guide, overview)) makes the grounding signal visible in the response.
  • No-results fallback prohibition — if search_hero_docs returns nothing, the LLM must say so rather than silently fall back to training data.

Regression testtest_mandatory_grounding_directive (new) asserts presence of the MANDATORY + search_hero_docs + Hero Vired markers in the rendered prompt. This addresses the issue body's section-2 concern ("the rebuild story is fragile — prompt.rs edits were silently no-op'd across rebuilds because the binary on disk wasn't the latest"): any future softening of the directive, OR a build-cache miss producing a stale binary that doesn't include the directive, fails CI at cargo test -p hero_agent.

The service-agent rebuild concern from section 2 is otherwise resolved — service_agent.nu (home#135) is now live and svc_cargo_install does a deterministic rebuild + copy each invocation.

Verification: cargo fmt --check -p hero_agent clean, cargo check -p hero_agent clean, all 7 prompt tests pass (including the new regression).

Meta-tracker: home#193.

Signed-off-by: mik-tf

Fixed in hero_agent commit `61d702d` on `development`. **Two soft lines** in `build_system_prompt()` Guidelines were replaced with one explicit MANDATORY directive: ```diff -- Use tools when needed rather than guessing -- When asked about Hero OS features or architecture, use search_hero_docs first +- MANDATORY GROUNDING: For ANY question that mentions Hero, hero_os, + hero_books, hero_agent, hero_aibroker, hero_router, hero_osis, + hero_foundry, hero_voice, hero_proxy, hero_browser, hero_collab, + hero_livekit, hero_proc, hero_skills, hero_archipelagos, or any + service starting with `hero_` — you MUST call `search_hero_docs` + BEFORE answering. Do not rely on training data: "Hero OS" is a + specific product (a sovereign digital workspace running in the + browser), NOT to be confused with "Hero Vired" (an unrelated + learning platform) or generic "hero" references. Always cite the + doc page in your reply (e.g. `(hero_os_guide, overview)`). If + search_hero_docs returns no results, say so explicitly rather than + falling back to training data. ``` Design choices that match the issue body's analysis: - **Lists every hero_* service we ship** so the LLM has a concrete trigger set, not a fuzzy "about Hero OS" check. - **MUST and BEFORE in uppercase** so the directive isn't read as guidance. - **Hero Vired disambiguation** — the most common training-data confusion observed in heronu testing. - **Citation requirement** (`(hero_os_guide, overview)`) makes the grounding signal visible in the response. - **No-results fallback prohibition** — if `search_hero_docs` returns nothing, the LLM must say so rather than silently fall back to training data. **Regression test** — `test_mandatory_grounding_directive` (new) asserts presence of the MANDATORY + search_hero_docs + Hero Vired markers in the rendered prompt. This addresses the issue body's section-2 concern ("the rebuild story is fragile — prompt.rs edits were silently no-op'd across rebuilds because the binary on disk wasn't the latest"): any future softening of the directive, OR a build-cache miss producing a stale binary that doesn't include the directive, fails CI at `cargo test -p hero_agent`. The service-agent rebuild concern from section 2 is otherwise resolved — `service_agent.nu` (home#135) is now live and `svc_cargo_install` does a deterministic rebuild + copy each invocation. **Verification:** `cargo fmt --check -p hero_agent` clean, `cargo check -p hero_agent` clean, all 7 prompt tests pass (including the new regression). Meta-tracker: home#193. Signed-off-by: mik-tf
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/home#149
No description provided.