Customize AI-Q Prompts and Models
Use this skill when a developer wants to change how an AI-Q agent reasons or
which model it uses — by editing a Jinja2 prompt template or by assigning a
different LLM to an agent role — usually without touching agent code. AI-Q agent
behavior is driven by prompts and config, so most tuning is a template or YAML
change. The one exception is adding a brand-new template, which needs a one-line
load_prompt wiring in the agent (see the prompt-templates reference).
Start Here
- Confirm the change is prompt or model customization, not new tool/agent logic.
For a new retrieval source use
aiq-add-data-source; for a new tool use
aiq-add-tool.
- Read the authoritative docs and the existing templates/config below first.
- Prefer editing an existing template or config field over adding new machinery.
- Keep the prompt's STRICT citation rules intact, and never hard-code a model
name where an
llms: ref belongs.
- Keep templates general-purpose: don't hard-code specific queries, domains, or
source/tool names — those come from the user's request and the
data_source_registry at runtime.
Authoritative References
docs/source/customization/prompts.md: prompt guide — template inventory,
load_prompt(path, name), render_prompt_template(template, ...), the
documented template variables, the STRICT citation rules, and "Creating a New
Template". Note it does not document every template's variables (e.g.
source_router.j2, writer.j2, source_registry.j2) — the .j2 files are
authoritative for the variables they actually use.
docs/source/customization/swapping-models.md: choosing hosted vs. self-hosted
NIMs and pointing config at them.
docs/source/customization/configuration-reference.md: the llms section and
each agent's config fields (deep_research_agent, clarifier_agent, …).
src/aiq_agent/common/prompt_utils.py: load_prompt and
render_prompt_template.
src/aiq_agent/common/llm_provider.py: LLMRole and LLMProvider.configure,
which bind a resolved LLM to an agent role (used by the deep research agent).
- Templates to model on:
src/aiq_agent/agents/deep_researcher/prompts/*.j2
(orchestrator, planner, researcher, source_router, writer) and
src/aiq_agent/agents/clarifier/prompts/*.j2. Other agents have prompts too
(e.g. shallow_researcher, chat_researcher) — check
src/aiq_agent/agents/*/prompts/.
Longer procedures live in this bundle:
- references/prompt-templates.md: where templates
live, how they load and render, template variables, citation rules, and how to
edit or add one safely.
- references/model-selection.md: the
llms
section, per-agent LLM fields, role binding via LLMProvider, and swapping models.
Workflow
- Identify the target agent and whether the change is a prompt or a model.
- For a prompt: edit the relevant
src/aiq_agent/agents/<agent>/prompts/*.j2
template; keep its variables and citation rules intact (see the references).
- For a model: add or point an
llms: entry in the config and set the agent's
role field (e.g. orchestrator_llm, planner_llm, researcher_llm,
writer_llm, source_router_llm) to that ref — do not edit Python to swap a
model.
- Keep token cost in mind: prefer reordering static instructions before dynamic
content (KV-cache reuse) and a cheaper model for low-stakes roles.
- Validate (below): lint any changed Python, run the agent's tests, and
smoke-run the CLI against the config you changed.
- Summarize changed files and paste the validation evidence.
Validation
Run the narrowest checks first; broaden only if you touched shared code.
uv run ruff check src/aiq_agent # only if you changed Python
uv run pytest tests/aiq_agent/agents/<agent> # the agent's tests (a prompt-only edit may have none)
./scripts/start_cli.sh --config_file <your config> # smoke against the config you edited
Expected: the agent loads its templates without a Jinja2 error and runs with the
configured model. A bare ./scripts/start_cli.sh uses the fixed default
(configs/config_cli_default.yml), so pass --config_file to exercise your
change. For a prompt-only edit (which often has no dedicated unit test), the
smoke run is the real check; a config/prompt-only change needs no Python lint.
Common Mistakes
- Breaking a template variable or the STRICT citation rules in
docs/source/customization/prompts.md, which degrades report grounding.
- Hard-coding specific queries, domains, or source/tool names into a template,
which biases the agent toward one task and breaks generalization. Source/domain
selection is data-driven (
data_source_registry, source_router.j2); keep
prompts task-agnostic.
- Hard-coding a model name in Python instead of using an
llms: ref and the
agent's role field, so the model can no longer be swapped from config.
- Changing an agent's default model when you meant a single sub-role. The deep
research agent's default is
orchestrator_llm (there is no generic llm
field); the clarifier's default is llm. Editing the default shifts every
unset role.
- Introducing a large dynamic prefix that defeats KV-cache reuse and raises cost.
- Pointing an agent's role at a model whose entry is not defined in
llms:.
Related Skills
aiq-configure-workflow
aiq-add-tool
aiq-add-data-source
aiq-release-qa
aiq-prepare-pr
1---2name: aiq-customize-prompts-models3description: Use when customizing AI-Q agent behavior through Jinja2 prompt templates or per-agent model selection — editing prompts under src/aiq_agent/agents/*/prompts/, adding template variables, or assigning/swapping LLMs per agent role via config (the llms section plus per-agent fields like orchestrator_llm, planner_llm, researcher_llm, writer_llm, source_router_llm).4license: Apache-2.05---67# Customize AI-Q Prompts and Models89Use this skill when a developer wants to change *how* an AI-Q agent reasons or10*which* model it uses — by editing a Jinja2 prompt template or by assigning a11different LLM to an agent role — usually without touching agent code. AI-Q agent12behavior is driven by prompts and config, so most tuning is a template or YAML13change. The one exception is adding a brand-new template, which needs a one-line14`load_prompt` wiring in the agent (see the prompt-templates reference).1516## Start Here1718- Confirm the change is prompt or model customization, not new tool/agent logic.19 For a new retrieval source use `aiq-add-data-source`; for a new tool use20 `aiq-add-tool`.21- Read the authoritative docs and the existing templates/config below first.22- Prefer editing an existing template or config field over adding new machinery.23- Keep the prompt's STRICT citation rules intact, and never hard-code a model24 name where an `llms:` ref belongs.25- Keep templates general-purpose: don't hard-code specific queries, domains, or26 source/tool names — those come from the user's request and the27 `data_source_registry` at runtime.2829## Authoritative References3031- `docs/source/customization/prompts.md`: prompt guide — template inventory,32 `load_prompt(path, name)`, `render_prompt_template(template, ...)`, the33 documented template variables, the STRICT citation rules, and "Creating a New34 Template". Note it does not document every template's variables (e.g.35 `source_router.j2`, `writer.j2`, `source_registry.j2`) — the `.j2` files are36 authoritative for the variables they actually use.37- `docs/source/customization/swapping-models.md`: choosing hosted vs. self-hosted38 NIMs and pointing config at them.39- `docs/source/customization/configuration-reference.md`: the `llms` section and40 each agent's config fields (`deep_research_agent`, `clarifier_agent`, …).41- `src/aiq_agent/common/prompt_utils.py`: `load_prompt` and42 `render_prompt_template`.43- `src/aiq_agent/common/llm_provider.py`: `LLMRole` and `LLMProvider.configure`,44 which bind a resolved LLM to an agent role (used by the deep research agent).45- Templates to model on: `src/aiq_agent/agents/deep_researcher/prompts/*.j2`46 (orchestrator, planner, researcher, source_router, writer) and47 `src/aiq_agent/agents/clarifier/prompts/*.j2`. Other agents have prompts too48 (e.g. `shallow_researcher`, `chat_researcher`) — check49 `src/aiq_agent/agents/*/prompts/`.5051Longer procedures live in this bundle:5253- [references/prompt-templates.md](references/prompt-templates.md): where templates54 live, how they load and render, template variables, citation rules, and how to55 edit or add one safely.56- [references/model-selection.md](references/model-selection.md): the `llms`57 section, per-agent LLM fields, role binding via `LLMProvider`, and swapping models.5859## Workflow60611. Identify the target agent and whether the change is a prompt or a model.622. For a prompt: edit the relevant `src/aiq_agent/agents/<agent>/prompts/*.j2`63 template; keep its variables and citation rules intact (see the references).643. For a model: add or point an `llms:` entry in the config and set the agent's65 role field (e.g. `orchestrator_llm`, `planner_llm`, `researcher_llm`,66 `writer_llm`, `source_router_llm`) to that ref — do not edit Python to swap a67 model.684. Keep token cost in mind: prefer reordering static instructions before dynamic69 content (KV-cache reuse) and a cheaper model for low-stakes roles.705. Validate (below): lint any changed Python, run the agent's tests, and71 smoke-run the CLI against the config you changed.726. Summarize changed files and paste the validation evidence.7374## Validation7576Run the narrowest checks first; broaden only if you touched shared code.7778```bash79uv run ruff check src/aiq_agent # only if you changed Python80uv run pytest tests/aiq_agent/agents/<agent> # the agent's tests (a prompt-only edit may have none)81./scripts/start_cli.sh --config_file <your config> # smoke against the config you edited82```8384Expected: the agent loads its templates without a Jinja2 error and runs with the85configured model. A bare `./scripts/start_cli.sh` uses the fixed default86(`configs/config_cli_default.yml`), so pass `--config_file` to exercise your87change. For a prompt-only edit (which often has no dedicated unit test), the88smoke run is the real check; a config/prompt-only change needs no Python lint.8990## Common Mistakes9192- Breaking a template variable or the STRICT citation rules in93 `docs/source/customization/prompts.md`, which degrades report grounding.94- Hard-coding specific queries, domains, or source/tool names into a template,95 which biases the agent toward one task and breaks generalization. Source/domain96 selection is data-driven (`data_source_registry`, `source_router.j2`); keep97 prompts task-agnostic.98- Hard-coding a model name in Python instead of using an `llms:` ref and the99 agent's role field, so the model can no longer be swapped from config.100- Changing an agent's default model when you meant a single sub-role. The deep101 research agent's default is `orchestrator_llm` (there is no generic `llm`102 field); the clarifier's default is `llm`. Editing the default shifts every103 unset role.104- Introducing a large dynamic prefix that defeats KV-cache reuse and raises cost.105- Pointing an agent's role at a model whose entry is not defined in `llms:`.106107## Related Skills108109- `aiq-configure-workflow`110- `aiq-add-tool`111- `aiq-add-data-source`112- `aiq-release-qa`113- `aiq-prepare-pr`