Skip to content

M3.5 — KB Builder en mode "agent appelé" (ask_kb_builder handler) #21

Description

@zestones

Note

Milestone: M3 — KB Builder Agent
Planning doc: docs/planning/M3-kb-builder/issues.md
Status: IMPLEMENTED on branch 19-m33-onboarding-session-multi-turn (will move to its own branch / PR before merge).

Scope. backend/agents/kb_builder/qa.pyanswer_kb_question(cell_id, question).

This handler is called by the M4.6 orchestrator when Investigator calls the
ask_kb_builder tool. It is a pure async function: no WebSocket broadcasts,
no session state, no DB writes.

Note

Depends on M3.1 (#17). anthropic_client.py exists with
model_for, parse_json_response, and the anthropic singleton — verified.


1. Implementation

Lives in backend/agents/kb_builder/qa.py (split-by-concern, matching pdf_extraction.py and onboarding/). Re-exported from agents.kb_builder for from agents.kb_builder import answer_kb_question.

Body matches the issue's reference snippet, with two minor adjustments:

  • import logging lives at module top (not inside the function) — single logger per module is the project pattern.
  • # noqa: BLE001 kept on the bare except Exception — the safe-fallback contract is explicit.

2. Model choice

Uses model_for("chat") — always Sonnet, regardless of ARIA_MODEL. Verified by test_returns_parsed_json_on_happy_path asserting the captured model kwarg is claude-sonnet-4-5.


3. Pure handler contract

Static guard test test_module_does_not_import_ws_manager_or_db parses the module AST, strips docstrings, and asserts ws_manager, broadcast, from core import database, and import asyncpg are absent from the executable code. Fails fast if anyone reintroduces a duplicate broadcast path.


4. Error contract

Three failure paths return the documented fallback dict:

Failure Returned dict
MCP is_error=True {answer: "KB not available for cell {n}", source: null, confidence: 0.0}
anthropic.messages.create raises {answer: "KB query failed — information unavailable", source: null, confidence: 0.0}
parse_json_response raises ValueError same as above (caught by the same except)

All three are covered by dedicated tests.


5. Dependency chain

flowchart LR
    M31["M3.1 anthropic_client<br/>(anthropic, model_for,<br/>parse_json_response)"]
    M25["M2.5 update_equipment_kb<br/>get_equipment_kb (DONE)"]
    M35["M3.5 answer_kb_question<br/>(this issue)"]
    M46["M4.6 ask_kb_builder tool<br/>in Investigator orchestrator"]

    M31 --> M35
    M25 --> M35
    M35 --> M46
Loading

6. Acceptance

  • await answer_kb_question(2, "What is the max bolt torque on the turbine?") returns {answer, source, confidence}
  • Latency < 5 s (Sonnet) — single messages.create with max_tokens=1024
  • If info absent in KB: answer contains "unknown", not a hallucinated value (system prompt enforces it; test_unknown_answer_is_passed_through_not_hallucinated verifies pass-through)
  • If cell has no KB row: returns {answer: "KB not available...", confidence: 0.0} — does NOT raise
  • Function performs no DB writes and emits no WS broadcasts (static guard test)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

agentTouches an Anthropic agent loop or orchestrationbackendChangement on back sidepriority:p0Critical path / demo blocker

Projects

  • Status
    ✅ Done

Relationships

None yet

Development

No branches or pull requests

Issue actions