Tools and their limits
Every tool the agent can use is a small, written contract: what it accepts, what it returns, and what it refuses. Vaguely defined tools produce unpredictable behavior, and that is where most agent failures begin.
Software that acts on its own is mostly a question of permissions, not prompts. We build agents and automations for approvals, intake and triage, with written limits and tests against them.
You have probably seen the demo: a model reads a request, checks three systems and records the result. Your own process is less tidy. Supplier invoices arrive as PDFs without order numbers, tickets wait for the one person who knows where they belong, and every approval has an exception nobody wrote down. Before asking whether an agent can do this work, it is worth asking which parts are worth handing over, and what the agent should be allowed to do while it tries.
The list of proposed use cases grows every time someone reads a new article. We rank it against decisions instead of enthusiasm: which steps are slow and costly, or done differently depending on who is working that day. A use case that cannot answer these four questions is not ready to build, however good its demo looks.
Drafting, summarizing, finding information and proposing a next step, with a person reviewing every output before it affects anything. Simple to control, and often all the work needs.
It plans, calls tools and carries a task through to the end. Worth building when the steps are many and repetitive and the decisions are narrow enough to write down.
An agent doesn’t get a broadly privileged account and a prompt telling it to behave. It gets a defined set of tools, each with its own limits: this query, that endpoint, this range of values. When it acts for a person or a service, it is designed to carry only their permissions, not a wider set of its own.
Anything expensive or hard to undo waits for a person’s approval, such as releasing a payment or changing a master record. Everything else is logged as it happens, with the input, the tool, the parameters and the result, so anyone can reconstruct a decision weeks later. Uncertainty is designed in rather than left to chance, because an agent that guesses confidently is worse than one that stops and asks.
Prompts get most of the attention and matter least. We use agents in our own engineering workflows, and these four parts decide far more about how they behave than any prompt does.
Every tool the agent can use is a small, written contract: what it accepts, what it returns, and what it refuses. Vaguely defined tools produce unpredictable behavior, and that is where most agent failures begin.
By step nine, the agent may have forgotten step two, or carry so much history that it loses track of the task. Deciding what gets summarized, and what is fetched again only when needed, is a design decision.
Grading one answer is easy. A ten-step run that reached the right result the wrong way is much harder to judge, and it will fail differently next week. So the test set is made of complete runs.
An agent that reasons at length and calls the model repeatedly looks fine in a demo and becomes unaffordable on an endless queue. Token cost and processing time belong in the design, not in a surprise after the pilot.
Not every step is a job for a language model. Predicting which invoices will be paid late, or which tickets will escalate, is usually better served by a model trained on your own history. Before building one, we set up the simplest thing that could work, such as a rule, a moving average or last year’s figure, and every model after it has to beat that baseline. Many projects honestly end there.
When a model does earn its place, the work shifts to the parts that usually get skipped: one definition of each feature for training and production, versioned datasets and model files, monitoring that compares live data with what the model learned from, and a written way to retrain or roll back. If a rule can do the job, or nobody will act differently when the score changes, we will tell you so.
Agent projects fail early, when choosing what to automate, more often than they fail late. So the first step narrows the scope to one process and one clear definition of done.
We walk through the process as it is actually performed, including the exceptions people handle without noticing. Sometimes part of it needs a simple form, not an agent. You receive a written scope of what the agent will and won’t do.
Before any reasoning logic exists, we define the tools, their parameters and limits, and the identity the agent runs under. You review the tool definitions and the permission model, which is the document your security team will want to challenge.
We collect real cases, including the ones that went badly, and write down what a correct run looks like for each. You see the cases and the scoring method before agent code is written, and you can add your own.
The agent works on live tasks, but its actions are held for approval, so its proposals can be compared with what your team actually did. You review the proposals and the differences, which is where the best design feedback comes from.
Autonomy expands one type of action at a time, each with a rollback plan. You receive the run logs, the cost per run, dashboards, runbooks and alert thresholds, all in your own accounts.
Most of this is decided before we arrive: if you already have a cloud provider and a contract with a model provider, we use those. Where there is a real choice, we pick what your team can run without us.
Assume it will; the design question is what a wrong action can affect. Anything costly or irreversible waits for a person’s approval, and the rest is designed to be reversible. Every run is logged, so the failing step can be found instead of guessed at. What the agent may do unsupervised is set with your process owners, step by step, not assumed.
Describe the problem in a paragraph and we will tell you which service applies.