An AI agent for grant applications: what it's built for and where it stops
How an AI agent handled a real German R&D grant application: project structure, three working rules, browser control — and where it has to stop.
Most people build AI agents as faster typists. On a real grant application, that turned out to be the weakest use of one — and pointed to where the actual value sits instead.
The occasion was our own application for the German Forschungszulage (R&D tax credit). A Claude Code agent worked alongside us: reading source documents, deriving the assessment base, cross-checking it against the books, and filling out the portal form. This playbook describes how it was built, so you can rebuild it for your own rule-bound process — including the places where it didn’t work.
The procedure itself — two-stage, assessment base, the seven costly mistakes — is covered in the companion article Applying for the Forschungszulage. This one is only about how the agent works.
The agent lives in its own repository, github.com/locagoi/forschungszulage-leitfaden — private, because the akte/ folder holds real company data, but proof that this isn’t a concept, it’s a project we actually used to handle our own application.
The result, up front
The agent found three real errors in the documents:
- A flat 15% rate applied to R&D wages, based on a paragraph that regulates something completely different. It appears in several calculation templates in circulation. It doesn’t exist in the law.
- A gross salary that differed between two versions of the same document.
- A remaining balance on the contracted-services account that never showed up in the application — possibly unclaimed funding.
All three surfaced while cross-checking between sources. None while filling out the form. That’s the real lesson, and the reason the project structure below looks the way it does.
What it’s good for and what it isn’t
| Good fit | Not a good fit |
|---|---|
| Reading source documents and cross-checking them against each other | Logging into portals |
| Reconstructing figures from multiple sources | Final submission |
| Finding contradictions between documents | Supplying subject-matter facts that appear nowhere |
| Filling out form fields systematically | Making legally binding declarations |
| Reading field labels and limits | Judging whether an activity actually counted as research |
The dividing line is simple: the agent works with what’s documented. Anything only you know, you have to supply.
Step 1: project context that survives sessions
An agent forgets everything between sessions. So the state has to live in files, not in chat history. This structure has proven itself:
project/
CLAUDE.md entry point: people involved, status, working rules, references
reference/ subject-matter knowledge — generic, not case-specific
procedure.md
assessment-base.md
common-mistakes.md
case-file/ your own data — confidential
company-data.md
assessment-base.md
open-questions.md what's unresolved, with the amount at risk
timesheet.md
The split between reference/ and case-file/ is the most important part, and it should be technically enforced, not just a convention: the agent reads from reference/ before making any subject-matter argument, and writes only to case-file/.
That has two effects. Subject-matter claims are tied to a citable source instead of model knowledge. And when the content gets reused — a blog post, a training document, a proposal — it’s immediately clear which folder is safe to publish and which never is.
Step 2: the three working rules
These three sentences found two real errors in practice. They belong verbatim in CLAUDE.md:
Primary source beats summary. Wage tax certificate over payroll journal over your own spreadsheet. Where documents contradict each other, that’s an open question, not a rounding issue.
Never invent a number. Where an exact value is missing, state a range and flag it as open.
Never enter anything into a portal before reading the field label.
The first rule is the most valuable. Without it, an agent averages between contradictory sources or just takes the one it read last — which is exactly how an error disappears instead of standing out. With it, the contradiction becomes an entry in open-questions.md, with the amount at risk attached.
Applied to your own process, “primary source” means the document someone put their name to externally: the transmitted tax certificate, the signed contract, the bank statement. Not the internal spreadsheet built from it.
Step 3: source documents as context
Two approaches that complement each other:
Connect the document store. Through a Drive or SharePoint connection, the agent searches on its own. That beats manual uploads, because it also finds what you didn’t think to ask about. In our case, a decisive contract wasn’t in the grants folder at all, but in the HR folder — found through a full-text search for a phrase from it.
Upload individual files for anything not already in the store: invoices from the inbox, contracts from a signature service, screenshots.
Ranked by how useful they turned out to be as context:
- Wage tax certificates — the most reliable wage source, because they’re filed with the tax authority
- Contracts with employees and contractors — they determine classification
- Contractor invoices — registered seat, service description, amounts
- Bank statements — cash outflow during the fiscal year
- Profit and loss statement — for the cross-check
Step 4: the cross-check — this is where the value is
The step almost nobody does, and the one that produced all three findings: reconcile the figures you’re claiming against the books.
The sum of the claimed wages has to show up in the profit and loss statement — salaries, managing-director salaries, statutory social security contributions. Same for contracted services: the account should contain the claimed fees.
If a remainder is left over there, that’s the most interesting number in the whole project. Either it doesn’t belong — or it’s unclaimed funding nobody applied for. That question never gets asked without the cross-check.
The pattern generalizes: take the number you’re reporting, and look for it in the system that didn’t produce it. Two systems describing the same reality are the best error detector available.
Step 5: browser control — and what goes wrong
Portals can be driven via Playwright. Important: the agent opens its own browser window with its own profile. Your login in your regular browser doesn’t carry over.
The procedure that works:
- The agent opens the login page in the controlled window
- You log in yourself — password and certificate stay with you
- The agent takes over and continues working in the existing session
Passwords don’t belong in the chat, and an agent doesn’t need them either.
Three pitfalls that actually happened:
Don’t trust the status display. The portal’s green and red section icons are just characters. If an agent reads them from the page source, it regularly gets stale values — and reports “all green” while two sections are still open. Only a screenshot is reliable. If you’re working with an agent, insist on visual confirmation, not its description of the state.
Script-set values don’t stick. Modern forms keep their state in their own data model. A value written into an input field via script shows up on screen but never reaches the model — and is gone after saving. Only real keystrokes count. That’s slower, and it’s why an agent takes minutes instead of seconds per form.
Unsaved changes block navigation. Forms with unsaved state attach a leave-guard. For an agent, that shows up as a cancelled navigation or a blocking dialog. Save before every section change; if something still hangs, a new tab is the way out.
Where the agent has to stop
At submission. That’s irreversible and a legally binding declaration. An agent can prepare everything, but a human sets the final checkbox — after reading the draft.
On subject-matter facts. Whether an activity counted as research, which approaches failed, how many hours went to which project — only you know that. An agent that fills in such details produces plausible-sounding false statements in a document with a ten-year retention requirement.
A useful agent says, at this point, that it doesn’t know.
On assumptions that could pass as facts. Where an estimate is unavoidable, its estimated nature has to be marked as such. Good forms have a dedicated field for that.
The process, at a glance
1. Set up the case file, write down the working rules
2. Connect source documents, agent builds a document index
3. Derive figures, cross-check against the books
-> contradictions become open questions with amount at risk
4. Resolve open questions: tax advisor, your own records
5. Browser session: you log in, the agent fills out the form
-> require screenshots for status verification
6. Download and read the draft
7. You submit
Steps 3 and 4 are the actual work. Filling out the form is the easy part.
What carries over
The pattern extends beyond grant applications — anywhere a process has clear rules, is error-prone, and needs a hard human approval gate: year-end closing, tenders, certification audits, customs and export documentation, compliance evidence.
Three things carry over:
- Separate subject-matter knowledge from case data — technically, not by convention. That’s what later decides what’s safe to publish.
- Write down the working rules before the agent works. “Primary source beats summary” is one sentence, and it catches errors that would otherwise slip through.
- Invest in the cross-check, not the data entry. The agent is mediocre at filling things out and strong at reconciling. Most people build it the other way around.
Legal status as of August 2026. This is not tax or legal advice and does not replace a case-by-case review.
The same division of labor is built into GTM Goat: agents prepare, check against real data, and propose — approvals with outside consequences stay with a human. Try it free for 4 weeks, no credit card required.