How Factorial built an agent across 25+ products that respects permissions

One, the AI agent living in the center of Factorial's platform, is live for all 17,000 customers, answering from company data with the same access as the person asking, and trained to say 'I don't know' rather than guess.

Factorial CEO Jordi Romero saw a problem everywhere he looked: Factorial's customers were exposing sensitive data to save time.

HR managers were pasting employee salary data into ChatGPT. Finance teams were uploading expense reports to Claude.

Worse, this analysis was often wrong. Outside models lacked important context about the company and its processes.

Factorial's clients wanted the power of AI, but they needed it inside their HR platform.

The company and the project

Founded in 2016, Factorial is a Barcelona-based, all-in-one HR platform serving more than 17,000 companies across nine markets, valued at over $1 billion. In 2025, they made it their mission to develop ChatGPT-like intelligence that works directly with company data, without customers having to hand that data to an outside AI tool.

That became One: an agent living inside the platform that helps managers and HR admins understand their teams in natural language, and helps employees get clarity on policies and their own data.

"We don't want your employees to hand your data to an AI tool. We think the right thing is to put AI in the center of your data." — Jordi Romero, CEO, Factorial

Why Mastra

One started as CTO Ilya Zayats's own side experiment — connecting Factorial's GraphQL schema directly to a model. Nine out of ten questions came back wrong, but the tenth felt like magic, answered straight from Factorial's own schema. That was enough to justify picking a real framework: Factorial's Ruby-on-Rails backend and React/TypeScript frontend pointed to something TypeScript-native.

"When looking for a framework, I noticed there were two spectrums. Either something extremely high-level that kind of puts you in the church of their thinking and how you're supposed to build, or extremely low-level, where you need to wire everything together. Mastra was in the middle of that. There is no black magic." — Ilya Zayats, CTO, Factorial

Mastra provided the API layer, workflow abstractions, and LLM provider integrations the team needed — handling provider discrepancies and fundamentals like a memory layer so the team could focus on business problems rather than infrastructure.

Confronting the challenges

There were a few challenges with building an agent of this complexity:

Permissions: Factorial has hundreds of granular permissions — who can see salary bands, approve expenses above certain thresholds, or access performance reviews from specific departments. These permissions are core to the product. Any AI solution that bypassed them would be immediately rejected by clients.

Hallucinations: Any response from One could be read as official company communication. If the agent doesn't have full clarity on the data, it has to say "I don't know, please ask a human" — never invent one.

Wide product surface area: Factorial now spans more than 25 products. One needs to understand all of them in detail and know how to fetch data and execute actions across them all. Context size and needle-in-the-haystack retrieval were the primary limitations to solve.

Trust: Most customers' only reference point for AI is ChatGPT, so anything related to company or employment data has to be trusted completely.

Product decisions and optimizations

Ilya led a senior team of early adopters to design an architecture that would solve all of these issues. They decided to:

  1. Treat the agent as another client application: The agent calls the same GraphQL API that powers Factorial's frontend, so permission enforcement is automatic — there's no separate access layer, and no drift between what users can see and what AI can access.

  2. Move from dynamic schema to deterministic tools: Letting the agent write its own GraphQL queries didn't hold up. Factorial's schema has tens of thousands of similarly-named entities, and the agent kept hallucinating parameters, picking the wrong ones, or getting into loops. All fetching now goes through deterministic tools instead: the agent picks a business concept and supplies high-level params — filters, foreign keys — against pre-built query templates. Concept discovery still happens dynamically, returning not just the JSON schema of params but extra context and usage examples, so the LLM understands the area it's working in. The format is very similar to Anthropic's skills system, and it eliminated an entire class of hallucinations.

  3. Optimize data representation: TSV once outperformed JSON, using 30-40% fewer tokens with better recall. That held for months, until wider responses made models lose track of TSV's headers, so the team is migrating to a subset of JSON with similar savings — a reminder that what works has to be revisited every time the underlying models change.

  4. Build generative UI with shared state: The team wanted to solve more use cases than just data retrieval. Using CopilotKit's useCoAgent functionality, Factorial shares state between the frontend and the agent. Engineers and users can watch the agent build forms and surveys directly in the browser in real-time, greatly reducing manual interactions.

  5. Implement enterprise observability: The team started with Braintrust for AI tracing and built extensive evals.

All of this is orchestrated with a Mastra workflow that uses an LLM to route to the right agent branch.

When users ask follow-up questions, the system maintains context and reuses the previous results. The workflow was the best pick, as it allowed the team to clearly debug LLM decisions and guide them properly to the right branch, shrinking the context and the breadth of each task.

"The more time passed, the more our product was maturing and Mastra was maturing, the more I saw unification of the two — ripping out our own homegrown solutions and switching to the more native Mastra approaches, because in the end that was just easier than continuing to reinvent our own wheel." — Ilya Zayats, CTO, Factorial

Where One stands today

One is no longer a pilot — it's live for all 17,000 of Factorial's customers, running thousands of iterations a day across roughly 70 skills and 500 tools. It's also become a platform, not just a product: more than 30 internal teams now build their own skills and tools on top of it.

The main challenge right now is on the user experience side. The team is iterating a lot on the UI side figuring out how to weave AI into the day-to-day of their customers, so they really understand and they trust it.

"Building on Mastra was the right call because it was not staying in the way, and it was not pushing any kind of really limiting approach of building AI when no one knew how to build AI. It was a really right set of building blocks that allowed us to scale and to learn together with the industry." — Ilya Zayats, CTO, Factorial

Start building today

Quickstart