{% extends "base.html" %} {% block title %}Prompt System & Tool Injection — Maxim Docs{% endblock %} {% block meta_description %}How Maxim's LLM agent sees the world: prompt assembly, priority-based section dropping, scene-scoped tools, and NAc-driven tool learning.{% endblock %} {% block meta_keywords %}Maxim prompt system, prompt builder, tool injection, scene-scoped tools, LLM context, NAc tool learning, FearAgent, autonomy policy, agentic robotics{% endblock %} {% block meta_author %}Maxim Project{% endblock %} {% block og_site_name %}Maxim{% endblock %} {% block og_type %}article{% endblock %} {% block structured_data %} {% endblock %} {% block content %}
MAXIM
How the LLM Sees the World
How the LLM sees the world: prompt construction, tool discovery, and the learning feedback loop.
The agent's system prompt is assembled by prompt_builder.py with sections at different priority levels. When the token budget is tight, lower-priority sections are dropped. This means the LLM's context varies based on conversation length.
Key insight: The mode_context section (which explains filesystem rules, cognitive tools, and behavioral guidelines) is at NICE_TO_HAVE priority and is frequently dropped. The agent often operates with just identity + tools + foundational rules.
The identity section (build_identity_section()) is at CRITICAL priority and always present. It contains:
The SIMULATION ENVIRONMENT block appears when _sim_active is True. The INTERACTIVE MODE block appears when InteractiveMode.ON. Both are in the identity section so they're never budget-dropped.
| Source | Priority | When Used |
|---|---|---|
TOOL_DESCRIPTIONS dictmodes/definitions.py |
Primary | All built-in tools. Contains description, params, example, followup_type. |
Tool.description + Tool.input_schematools/base.py |
Fallback | User-registered tools, SEM affordance tools, anything not in TOOL_DESCRIPTIONS. |
Tip: If a tool is registered but the LLM never calls it, check whether it has an entry in TOOL_DESCRIPTIONS. The fallback description from the Tool class is often too terse for the LLM to understand when to use it.
The agent learns which tools work through the NAc causal learning system:
| Mechanism | What It Does | Where |
|---|---|---|
| Direct attribution | Records tool outcomes to NAc: (context, tool) → success/pain |
ToolPainBridge |
| Causal links in prompt | LLM sees learned tool-outcome associations in context_pool | prompt_builder.py |
| Recent outcomes | Last N tool results shown in prompt for immediate context | agent_loop.py |
| Relevance filter | Learned index trims tool manifest to relevant subset (passive mode only) | LearnedToolIndex |
Tool learning is indirect — NAc learns outcome associations that appear in the prompt as context, but the LLM still sees the full tool manifest. Learning influences when to call a tool, not whether it appears.
| Tool Category | AUT (Agent Under Test) | Orchestrator |
|---|---|---|
| Filesystem (read, write, bash) | Yes (sandboxed) | No |
| Sim tools (send_message, observe_actions) | No | Yes |
| Introspection (memory_recall, causal_links) | Yes | No |
| Interactive (request_interaction, set_scene) | Yes | No |
| Robot (move, track_target) | Deregistered | Not added |
| Response (respond, speak) | Yes | sim_respond only |
Tool subclass in src/maxim/tools/ with name, description, input_schema, and execute()build_tool_registry() (runtime/bootstrap.py)TOOL_DESCRIPTIONS (modes/definitions.py) with description, params, example, and followup_typeallowed_tools whitelist (simulation/orchestrator.py) if it should be usable in simulationinput_schema, verify _validate_input() handles it (tools/base.py detects both formats)registry.register_scene_tools(tools, scene_id="...") instead of register(). Scene tools are deactivated on scene transition (not deleted) and can be re-activated. The executor gates on active status — deactivated tools return a descriptive error.Common pitfall: A tool can be registered and allowed but the LLM never calls it because:
TOOL_DESCRIPTIONS (fallback description too terse)input_schema causes silent validation failure in _validate_input()| File | Role |
|---|---|
agents/prompt_builder.py | Section assembly + budget management |
agents/llm_worker.py | Delegates to prompt builder, submits to LLM |
modes/definitions.py | Mode definitions + TOOL_DESCRIPTIONS dict |
runtime/bootstrap.py | build_tool_registry() — canonical tool registration |
runtime/autonomy.py | Execution-level tool gating (not prompt-level) |
simulation/orchestrator.py | AUT vs orchestrator tool registry setup |
tools/base.py | Tool base class + _validate_input (JSON Schema support) |
api.py | register_tool() / @maxim.tool dynamic registration |