# Add a tool

> Use your coding agent and UiPath skills to add a tool to the LangGraph agent.

## Step 7 - Add a live lookup tool

Right now the agent is guessing from vibes: nothing it says about a dragon or a goblin is checked against anything real. To improve the accuracy of the classifier, let's add a tool to verify quest information before finalizing a tier recommendation. To do this, the tool will use the [Open5e API](https://open5e.com/api-docs) to search for creatures published under the 5e System Reference Document (SRD).

This is standard LangGraph, not a UiPath-specific trick: a plain Python function decorated with `@tool`, bound to the model, and the model decides at runtime whether calling it is worth it. Your coding agent wires up that binding syntax for you.

Ask your coding agent:

```text
Update main.py to add one Python tool to the existing LangGraph agent: a function that looks up a monster's challenge rating from the Open5e SRD API and uses it to inform the difficulty tier.

Tool behavior:
- Query GET https://api.open5e.com/v2/creatures/ using the `requests` library (already available as a transitive dependency; add it directly with `uv add requests` only if the import fails), with query parameters: name__icontains=<creature name or type the model supplies>, document__key__in=srd-2024, limit=10, fields=key,name,type,size,challenge_rating,alignment
- Set a 10-second timeout on the request, and call raise_for_status() before reading the response body — this is a live external API call, so it should fail fast with a clear error instead of hanging or raising a confusing KeyError if Open5e is slow or returns a non-200 response.
- If the response has zero results, return that as-is — nothing further to do.
- If the response has more than one result, return the full list and let the agent pick the best match rather than guessing which one is correct.
- Bind the tool with the standard LangChain @tool decorator. Let the model decide when to call it based on the tool's description — don't force a call on every input.
- Name the tool function `get_challenge_rating`.
- In the tool's docstring, describe what counts as a creature in the abstract — don't include a named example creature (e.g., avoid phrasing like "e.g. goblin, young red dragon"). A concrete example name in the docstring can get echoed back by the model as a spurious lookup for a creature that isn't actually in the quest.

Update the system prompt so that:
- The agent calls this tool whenever the quest description names or strongly implies a specific creature.
- Only call the tool for creatures explicitly named or strongly implied in the quest description — never for other creatures used as a comparison or reference point.
- When a `challenge_rating` comes back, the agent uses it to inform the tier classification and cites it explicitly in the `reasoning` output field. Do not fabricate or guess a challenge rating from memory — only cite one that actually came from the tool's response.
- If no tool call happens, or the tool returns zero results, the agent classifies using its existing judgment, same as before.
- Don't add new output fields. The State schema stays `tier` and `reasoning` only — the challenge rating goes into the reasoning text, not a new field.

Only touch main.py.

Don't run any uip codedagent commands or otherwise verify that the agent runs — I will do this myself.
```

:::note
**Why this prompt is so specific.** As in Step 5, the file scoping and the instruction not to run or verify anything is deliberate: the next commands in this lab exercise the tool directly, so verification is left to you.
:::

As you adapt the prompt to your own work, you are again advised to remove the last two sentences to fully enable your coding agent to exercise your code.

:::important
**Coding agents are non-deterministic.** Your generated tool code will differ from any examples shown here; that is expected. What matters is that `main.py` still runs without errors and calls the tool only when a creature is named.
:::

This tool does not add or change any input or output fields, so there is no need to re-run `uip codedagent init` this time. Only re-run it when your Input/Output models change.

Re-run the dragon example from Step 6:

```bash
uip codedagent run agent '{"description": "Slay the ancient red dragon terrorizing the countryside"}'
```

Watch the trace this time: the agent calls the SRD lookup, gets back a real challenge rating, and cites it in its reasoning instead of just asserting Legendary. That's the difference between a text classifier and an agent that can go verify itself.

---

With the tool wired in, you are ready to test that the agent uses it correctly and scores well across a range of inputs.
