nestonexStart a project
AI AND LLM ENGINEERING

Typed tool calling

How do you let a language model take an action without letting it invent one?

Give it a fixed set of functions with typed, validated arguments, and treat what it produces as a proposal rather than a decision. The proposal then passes the same schema validation, policy limits and authorisation as any other request. The model chooses among actions you defined; it never defines one.

Intent architecture: a language model proposes a typed intent which passes schema validation, policy limits and a two-factor gate before execution
System architecture · Axon Wallet

What tool calling actually is

You describe a set of functions to the model — their names, their parameters and the types of those parameters. When the model decides one applies, it emits a structured call naming the function and its arguments, rather than prose describing what should happen.

The value is in what it removes. Without it, a model that wants something done writes a sentence, and your code has to parse that sentence into an action, which fails in ways that are difficult to enumerate and impossible to test exhaustively. With it, you get a typed object you can validate before anything happens.

It is worth being precise about what the model is doing: choosing among options you defined and filling in arguments. It is not writing code, and it is not gaining access to anything you did not give it a function for.

Why the model must not be the thing that decides

A model choosing correctly nearly all the time is not the same as a system that is safe, because the failures are not random. They cluster around ambiguous phrasing, unusual amounts and inputs written by someone trying to cause them.

So the architecture that works separates proposing from deciding. The model proposes a typed intent. That intent then passes the same schema validation, the same policy limits and the same authorisation as a request originating from a button in the interface. If a human would need two-factor for this action, so does the model.

Done that way, the blast radius of a wrong model output is bounded by the checks, not by the model's judgement. And the checks are ordinary code: readable, testable, and reviewable by someone who has never thought about prompts.

Designing the tools themselves

Narrow beats general. A tool called transfer_funds with free-form parameters puts every decision in the model's hands. Several specific tools with tight types — an enum of supported assets, a bounded amount, a destination that must already exist in the user's address book — put most decisions in the schema.

Make the types do the work. Enumerations instead of strings, explicit units instead of implied ones, and required fields that cannot be guessed. Every constraint in the schema is one the model cannot violate, validated before your code runs.

Design the refusal. A model with no correct tool for the situation should have an obvious way to say so and hand off to a person. Without that, it picks the closest tool, which is the worst available outcome.

And treat read and write differently. Reads are cheap to make safe. Writes need limits, approvals and an audit trail, and their number — not the number of prompts — is what drives the cost of the work.

Prompt injection is the reason this matters

If a model reads untrusted text and can also call tools, that text is in a position to steer the tools. A document, an email, a web page or a chat message can carry instructions, and the model has no reliable way to distinguish content from command.

This is not fixed by asking the model to ignore instructions in documents. It is fixed by ensuring that a successfully manipulated model still cannot do anything the policy layer would not permit: limits on amount, allow-listed destinations, human approval on anything irreversible.

Which is the same design as above, arrived at from the security direction. Assume the model can be persuaded, then check what it is still able to do.

How we have used it

In Wen, the in-app AI agent cannot move funds directly. The keys sit in embedded wallets the backend never holds, and the agent calls typed, validated tools that go through the same checks as a tap in the interface. The agent can propose a trade; it cannot invent one.

Axon Wallet makes the split explicit: a language model turns a plain-language request into a typed intent, and that is all it does. The intent then passes JSON Schema validation, policy limits and a two-factor gate before any transaction reaches Solana, EVM or Sui. Proposing and deciding are different jobs, done by different parts of the system.

COMMON QUESTIONS /

Questions people also ask

What is the difference between tool calling and function calling?

Nothing meaningful — they are the same mechanism under two vendor names. Both mean giving a model a schema of callable functions and receiving a structured call back. Details of the wire format differ between providers, which is a portability consideration rather than a conceptual one.

Can a model call a tool it was not given?

It can emit something that looks like one, and your code must reject it. Validate the function name against the allow-list and the arguments against the schema before dispatching anything. Never dispatch on a name the model produced without checking it exists.

How many tools is too many?

Accuracy degrades as the set grows and the descriptions start to overlap, and the practical ceiling is lower than most vendor limits. If a workflow needs dozens, it is usually better split into scoped assistants with small tool sets than served by one assistant holding all of them.

Should a tool call ever run without human approval?

Reads and reversible actions, yes. Anything that moves money, changes permissions, sends external communication or cannot be undone should have a person in the path, or a hard limit low enough that the worst case is acceptable. That threshold is a business decision and belongs in the proposal.

THE PROOF /

Where we have actually done this.