# Aiq Add Tool

> Use when adding or changing a general-purpose AI-Q tool (a NeMo Agent Toolkit function) under sources/, defining its FunctionBaseConfig schema, registering it with @register_function, wiring it into an agent's tools list, or testing it.

- Skill: `nvidia-ai-blueprints-aiq/aiq-add-tool` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add nvidia-ai-blueprints-aiq/aiq-add-tool`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nvidia-ai-blueprints-aiq/aiq-add-tool/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: Apache-2.0
- Author: NVIDIA-AI-Blueprints (https://skillmd.com/u/nvidia-ai-blueprints-aiq)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/nvidia-ai-blueprints-aiq/aiq-add-tool

---


# Add an AI-Q Tool

Use this skill when a developer wants to add a general-purpose tool to AI-Q — a
NeMo Agent Toolkit (NAT) function such as a web search, calculator, or code
helper. The tool is a package under `sources/`, registered with
`@register_function` and referenced directly in an agent's `tools` list.

## Start Here

- Confirm this is a **general utility tool**. If it is domain-specific retrieval
  that should appear as a toggleable source in the UI, use `aiq-add-data-source`
  instead — a data source is the same NAT function plus a `data_source_registry`
  entry. This skill stops at wiring the tool into an agent.
- Read the authoritative files below before editing.
- Copy the closest existing tool package rather than inventing a new shape.
- Never print or commit API keys; resolve secrets at runtime via `SecretStr`.

## Authoritative References

- `docs/source/extending/adding-a-tool.md`: canonical 8-step walkthrough; the
  workflow below mirrors it.
- `sources/tavily_web_search/`: minimal tool package.
- `sources/google_scholar_paper_search/`: tool package with a separate client,
  a graceful missing-secret stub, and tests.
- `docs/source/extending/adding-a-data-source.md`: "Data Source vs. Tool" — a
  data source is architecturally identical to a tool; only the registry wiring
  differs.

Existing tools to model on: `tavily_web_search`, `exa_web_search`,
`paper_search` (Google Scholar), `knowledge_retrieval`.

Longer procedures live in this bundle:

- [references/nat-function-pattern.md](references/nat-function-pattern.md):
  package layout, config class, registration, the missing-secret stub, the
  `pyproject.toml` entry point, and wiring the tool into an agent in YAML.
- [references/testing.md](references/testing.md): unit-test pattern and the
  install/test/lint validation commands.

## Workflow

1. Pick the closest existing package under `sources/` and inspect its layout.
2. Create `sources/<my_tool>/` with `src/register.py`, a client module,
   `pyproject.toml`, and `tests/`.
3. Define a `FunctionBaseConfig` subclass with a stable `name=` (this becomes the
   YAML `_type`); resolve any API key via `SecretStr`.
4. Register an async `@register_function` that yields a `FunctionInfo`; yield a
   graceful stub when a required secret is missing.
5. Add the `[project.entry-points."nat.plugins"]` entry and install the package
   editable.
6. Reference the tool in a config under `configs/` (under `functions:`, then in
   an agent's `tools:` list).
7. Add focused tests; run the validation commands below.
8. Summarize changed files and paste the test/lint evidence.

## Validation

Run the narrowest commands first; broaden only if the change touches shared code.

```bash
uv pip install -e ./sources/my_tool
uv run pytest sources/my_tool/tests
uv run ruff check sources/my_tool
uv run ruff format --check sources/my_tool
```

Expected: the package installs, its tests pass, and Ruff reports no lint or
format failures for the new tool package.

## Common Mistakes

- Omitting the `[project.entry-points."nat.plugins"]` entry in `pyproject.toml`,
  so NAT never discovers the registration at import time.
- Crashing on a missing API key instead of yielding a stub that returns a clear
  error string.
- Raising exceptions from the tool function; tools must return error messages as
  strings so they never crash the agent.
- Weak docstrings: the LLM uses the function docstring as the tool description to
  decide when to call it — state what it does, when to use it, and what it returns.
- Printing API keys or embedding secrets in YAML instead of using environment
  variables or `SecretStr`.

## Related Skills

- `aiq-configure-workflow`
- `aiq-add-data-source`
- `aiq-release-qa`
- `aiq-prepare-pr`

