Giving AI employees tools

Tools for four AI employees on Agent Runtime: split by role, read only first, deployed on merge. The 401 that Agent Identity's certificate-bound tokens caused, Google Search next to our own tools, and the first write through our API instead of the database.

By Marian Vladoi, 2026-10-24

In part 4 we built a small company of AI employees: a CTO, a FinOps Lead, a Sales and a Marketing agent, each on its own on Agent Runtime, with a board of tickets and a meeting room. They could talk well. But they could not see anything: ask the Sales Agent about today's leads and it could only say it had no data.

This part is about giving them tools. We gave each of the four the tools its role needs, deployed them automatically, and checked every one in production. Most of it was straightforward. The parts that were not are the reason for this article.

Start with a list, then split it by role

We first listed every source of data we already had: the contract roles and leads our radars find, the contact form, the LinkedIn posts and their results, site visits, the weekly cloud releases, the planner board and Google Cloud's price list. Then we gave each one to the employee whose job needs it, and to nobody else:

  • Sales: contract roles, leads, new contact messages and the CEO's profile;
  • Marketing: posts, post results, site visits and the week's top releases;
  • CTO: the planner board and the week's top releases;
  • FinOps Lead: Google Cloud's official list prices.

Two rules held for every tool:

  • Read only first. A tool that can only read cannot send, delete or spend anything. We added the first write much later, on purpose (more on that below).
  • Return less than you have. Each tool returns at most 20 items, cuts long texts and leaves out what the agent does not need. The contact messages go to the agent without email addresses: it can help draft a reply without ever holding the address. We updated our privacy policy to say exactly that.

Then every employee got the same three "everyday" tools: today's date, Google Search, and their own tickets on the board.

The date sounds trivial. It is not: a model does not know what day it is, and "follow up next Monday" or "this week's releases" are wrong without it. A tool that returns the date, the day and the week number costs nothing and removes a whole class of mistakes.

Deploy on merge, only what changed

Four agents and frequent changes meant manual deployments would not last. We set up a Cloud Build trigger on the agents/company/ folder:

  • for each agent, the build computes a fingerprint of its files (tests and local files left out) and compares it with the one saved for its last deployment in Cloud Storage;
  • only agents whose fingerprint changed are deployed, one at a time, with agents-cli deploy --update-only;
  • the build has its own service account with only what it needs.

The first build deployed all four, because none had a fingerprint yet; we saved one for the agents that were already up to date. Updates do not change permissions, so new IAM roles for an agent stay a deliberate step done by hand. Two builds started a minute apart once tried to update the same agent; one failed with "not in ACTIVE state: UPDATING". Harmless, but a reminder that a build pipeline needs to be designed for a second build arriving early.

The surprise: 401 with the right permissions

The tools passed every unit test, deployed fine, and in production every one of them failed with 401 Unauthorized. The agents' identities had the right role. Nothing looked wrong.

The cause is a security feature of Agent Identity. By default, its access tokens are bound to the agent's certificate: Google accepts them only on an API's mTLS endpoint (firestore.mtls.googleapis.com, not firestore.googleapis.com), over a connection that presents that certificate. A stolen token is useless anywhere else. Our database client library connected to the normal endpoint, so every call was refused.

The fix was small once we understood it. We wrote a tiny read-only Firestore client over REST, using AuthorizedSession.configure_mtls_channel() from google-auth: it finds the agent's certificate and connects to the mTLS endpoint. On a laptop, without a certificate, the same code uses the normal endpoint. Then a second, smaller surprise: Agent Runtime gives the agent the project number, and Firestore's REST paths need the project ID, so the next error was a 404.

There is a switch to turn the binding off (GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKEN=false). Google advises against it, and so do we: the binding is exactly what makes an agent's credentials safe if they leak.

One API still answers 401 for us on its mTLS endpoint: the Cloud Billing price catalog our FinOps Lead reads. Its answers say so honestly for now, and fixing it is the next ticket on the board.

A failing tool should not end the answer

Before the fix, a failing tool did something worse than fail: the agent returned an empty answer. The error ended its turn.

Every tool is now wrapped so that an error becomes a short result, {"error": "This data could not be read right now."}, logged on our side. The agent reads it and tells you plainly that it could not reach the data, instead of going silent or, worse, guessing. Their instructions say the same: use only what a tool returns, and if a tool fails or returns nothing, say so.

Google Search next to your own tools

Gemini's Google Search grounding is a built-in tool, and a model call cannot mix it with your own function tools. ADK offers a shortcut, GoogleSearchTool(bypass_multi_tools_limit=True), which runs the search as a small agent of its own next to the other tools.

It worked on a laptop and failed in production: some employees returned empty answers whenever they searched. The logs said 'dict' object has no attribute 'model_dump'. The shortcut passes the search's sources up to the employee as a plain dictionary, and Agent Runtime's session store, which saves every step of a conversation, could not save it. Locally, sessions live in memory and nothing is saved, so no test could see it.

We now wrap the search ourselves: a small agent whose only tool is Google Search, called by each employee as a tool, which writes its sources (the site and the link) in its answer. To reproduce the bug before the fix, and to check the fix, we ran the agent on a laptop with the same session store as production. That is worth doing for any agent before you trust a green test run.

The employees are told to say what they found on the web and where, and never to present a web result as the company's own data.

Search is the one tool here that costs per use: Google gives a monthly allowance of free searches, then charges per thousand. Only the searches the agent decides to run count.

The first write: through our API, not the database

Reading is safe. The next step was for an agent to check its tickets and propose a solution on each, for the CEO to approve, deny or comment on.

The simple way would be to give the agents write access to the database. But Firestore permissions apply to the whole database: an agent allowed to add a comment could also change any other document. Our code would never do that, but the permission would allow it.

So agents write through the website's API, like any other client:

  1. The agent asks Google for an ID token of its own identity, for our API as the audience. No password or key is stored anywhere.
  2. Our API verifies the token: the signature against Google's public keys for our agents, the issuer, the audience and the expiry. The token's subject is the agent's unique identity, which tells us exactly which employee is calling.
  3. The API applies the business rules: the ticket must be assigned to that agent and not finished, and an agent can have only one proposal waiting. It can propose again once the CEO has approved, denied or commented.

The agents keep read-only access to the database. Everything they can change goes through one endpoint, with rules we can read in one place and test like any other code.

On the board, each proposal now has Approve and Deny next to it, and comments carry the conversation. The agent reads the thread the next time it checks its tickets and proposes again, taking the answer into account.

Ask them what they can do

Once the employees had tools, we wanted to see them, so we asked each one, "Which tools do you have?" They all answered correctly and in their own words, and the Team page now lists each employee's tools.

There was one lesson: an agent can describe its tools a little wrong. One said its profile tool included day rates; it does not. So the list on the Team page is not written by hand. A test reads each agent's code and fails if the published list and the real tools ever differ.

We also had to update the evaluation judges. Our "no invented facts" judge, from part 4, began to fail correct answers: a lead's name read from a tool looked invented to it. The judges now know which tools each employee has, and that facts read from them are allowed.

What it costs

  • The read tools are a few small database reads per answer.
  • The date tool is free.
  • Google Search is free up to the monthly allowance, then billed per thousand searches.
  • The deployment pipeline uses Cloud Build's free minutes.
  • The agents still scale to zero when nobody asks them anything.

What to consider before you give agents tools

  • List your data first, then split it by role. An agent with every tool is harder to trust and to test than one with the four it needs.
  • Start read only, and return the minimum. Leave out personal data the task does not need.
  • Check the identity's token rules on day one. With Agent Identity, use the mTLS endpoints; do not switch the protection off.
  • Make tool errors part of the answer, never an empty one.
  • Give agents today's date. It is the cheapest tool you will ever add.
  • Test with the production session store, not only in memory: some failures happen only when a step is saved.
  • Put the first write behind your own API, with the agent's own identity and the rules in your code, not behind a wide database permission.
  • Keep a human decision on every proposal, with approve, deny and comments, and keep it written down.
  • Let a test, not a person, keep your documentation of the tools true.

The employees can now see their part of the company, tell what day it is, look things up and propose work on their own tickets. They still do not do the work. That is the next dial to turn, one approved tool at a time.

Thinking about AI employees for your team? Plan your AI team on Google Cloud and get a rough size for a first version.