DEV Community

Gael Anaya Carballo
Gael Anaya Carballo

Posted on

Your AI Agent Isn’t the Problem: Your Documents Are Still Unusable

Most AI agent workflows don’t fail because the model is incapable.

They fail because the model receives the wrong input.

A typical business workflow might start with an invoice PDF, a scanned contract, an Excel spreadsheet, a Word document, an email attachment, or some raw HTML copied from an internal system.

The agent is then expected to:

  • Understand the document
  • Find the relevant information
  • Distinguish facts from noise
  • Preserve numbers and dates correctly
  • Compare the document with other sources
  • Apply business rules
  • Return a predictable result
  • Trigger the next step in an automation

Sometimes it works.

Sometimes the output looks convincing but contains a wrong number, a missing clause, a changed field name, or a slightly different structure that breaks the next node in the workflow.

This is the part of AI automation that is often underestimated: before an agent can reason about a document, the document needs to become usable data.

The document problem behind many agent failures

When people talk about AI agents, they usually focus on the reasoning layer.

They discuss:

  • Which model to use
  • How many tools the agent should have
  • Whether to use LangGraph, CrewAI, AutoGen, or another framework
  • How to create planning loops
  • How to give the agent memory
  • How to reduce hallucinations
  • How to make the agent autonomous

All of those decisions matter.

But in many real-world workflows, the biggest problem appears earlier.

The agent is connected to documents that were never designed to be consumed by software.

A PDF is designed to be read by a person. An Excel workbook may contain merged cells, inconsistent headers, notes, formulas, several tables, and multiple sheets. A Word document may mix paragraphs, tables, signatures, and legal clauses. A scanned image may contain information that is visually obvious to a human but difficult to extract reliably.

The agent has to solve the document problem and the business problem at the same time.

That creates unnecessary uncertainty.

Imagine an invoice-processing workflow. The actual task may be simple:

  1. Read the invoice.
  2. Extract the invoice number.
  3. Identify the supplier.
  4. Read the total amount.
  5. Compare it with a purchase order.
  6. Notify the finance team if there is a mismatch.

The difficult part is often not the comparison.

The difficult part is making sure that the invoice number, supplier name, currency, tax amount, and total are extracted consistently before the comparison happens.

Why sending the entire file to an agent is fragile

A common first approach is to send the complete file directly to a general-purpose AI model and ask it to handle everything.

For example:

Read this contract, identify the renewal clause, compare it with our policy, summarize the risks, and return JSON.
Enter fullscreen mode Exit fullscreen mode

This can work for prototypes.

However, production workflows usually need stronger guarantees.

The output may change slightly between executions:

{
  "supplier": "Acme Ltd",
  "total": 1250,
  "currency": "EUR"
}
Enter fullscreen mode Exit fullscreen mode

Then, on another execution:

{
  "vendor_name": "Acme Limited",
  "amount_due": "€1,250.00"
}
Enter fullscreen mode Exit fullscreen mode

Both responses may look reasonable to a human. They are not equivalent to an automation.

A downstream workflow may be expecting:

supplier
total
currency
Enter fullscreen mode Exit fullscreen mode

If the model changes the key names, returns an amount as formatted text, or omits a field that was not explicitly visible, the workflow can fail silently.

There is another problem: context size.

If the workflow processes a 200-page PDF, the agent may receive far more information than it needs. This increases:

  • Token usage
  • Latency
  • Cost
  • Retrieval complexity
  • The chance of confusing similar sections
  • The amount of irrelevant context available to the model

The more content the model receives, the more important it becomes to control exactly what the model is expected to return.

A better separation of responsibilities

A more reliable architecture separates document processing from agent reasoning.

Instead of asking one general-purpose agent to do everything, the workflow can be divided into layers:

Document
   ↓
Extraction and normalization
   ↓
Validated structured data
   ↓
Business rules and agent reasoning
   ↓
Action or human review
Enter fullscreen mode Exit fullscreen mode

Each layer has a different job.

1. Document extraction

This layer reads PDFs, images, spreadsheets, Word documents, or raw text and identifies the relevant fields.

2. Normalization

This layer converts different labels and formats into a consistent structure.

For example:

  • Invoice No.
  • Invoice Number
  • Factura
  • Nº factura

can all map to:

invoice_number
Enter fullscreen mode Exit fullscreen mode

Likewise:

  • Total
  • Amount Due
  • Grand Total
  • Importe total

can map to:

total_amount
Enter fullscreen mode Exit fullscreen mode

3. Validation

The workflow verifies that the output follows the expected schema and checks important constraints:

  • Is the invoice number present?
  • Is the amount numeric?
  • Is the currency known?
  • Does the total equal subtotal plus tax?
  • Is the date valid?
  • Is the document readable?
  • Does the supplier match the expected company?

4. Reasoning

Only after the document has been transformed into usable data should the agent evaluate business logic.

For example:

Does this invoice exceed the purchase order by more than 5%?
Enter fullscreen mode Exit fullscreen mode

That is a much narrower and more reliable task than asking the same agent to interpret the entire PDF, locate all values, understand the purchase order, and make the comparison from scratch.

Introducing Claix

Claix is a server-to-server document intelligence API designed for this layer between unstructured files and AI workflows.

The core idea is simple:

Send a document and a schema. Receive structured data that your workflow can actually use.

Claix can process:

  • PDF files
  • Excel and CSV files
  • Word documents
  • Plain text
  • Markdown
  • HTML
  • XML
  • Images
  • Scanned documents

The result is JSON shaped around a schema defined by the developer.

For example, an invoice schema might look conceptually like this:

{
  "name": "Supplier Invoice",
  "type": "pdf-json",
  "schema_definition": {
    "invoice_number": {
      "type": "string",
      "description": "The invoice identifier shown on the document"
    },
    "issue_date": {
      "type": "string",
      "description": "The invoice issue date in ISO format"
    },
    "supplier_name": {
      "type": "string",
      "description": "The legal name of the supplier"
    },
    "total_amount": {
      "type": "number",
      "description": "The final invoice total before or after tax according to the document"
    },
    "currency": {
      "type": "string",
      "description": "The currency used for the invoice total"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The schema becomes the contract between the document and the rest of the system.

A workflow does not need to guess whether the model will return supplier, vendor, or company_name.

It can request and consume a known structure.

A simple API workflow

Claix is designed for backend integrations, scripts, automation platforms, and agent tools.

A PDF extraction request can be sent using a multipart request:

const formData = new FormData();

formData.append(
  "schema_id",
  "3c7a9f21-4b8e-4d1a-9c6f-2e0d8a5b7c4f"
);

formData.append(
  "file",
  new Blob([fs.readFileSync("./invoice.pdf")]),
  "invoice.pdf"
);

const response = await fetch("[https://claix.dev/api/pdf-json](https://claix.dev/api/pdf-json)", {
  method: "POST",
  headers: {
    "x-api-key": process.env.CLAIX_API_KEY
  },
  body: formData
});

const result = await response.json();

console.log(result.data);
Enter fullscreen mode Exit fullscreen mode

A successful response follows a predictable structure:

{
  "success": true,
  "schema_utilizado": "Supplier Invoice",
  "total_registros": 1,
  "data": [
    {
      "invoice_number": "INV-2026-00456",
      "issue_date": "2026-03-14",
      "supplier_name": "Acme Supplies Ltd",
      "total_amount": 1284.5,
      "currency": "EUR"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The important part is not just that the model understood the document.

The important part is that the result is ready to be passed into another system.

For example:

Gmail attachment
   ↓
Claix PDF extraction
   ↓
Validate invoice fields
   ↓
Find purchase order in ERP
   ↓
Compare values
   ↓
Send approval request or flag mismatch
Enter fullscreen mode Exit fullscreen mode

The same pattern works with n8n

A common n8n workflow might look like this:

Gmail Trigger
   ↓
Download Attachment
   ↓
HTTP Request to Claix
   ↓
Validate Extracted JSON
   ↓
Lookup Purchase Order
   ↓
Compare Invoice and Purchase Order
   ↓
Slack / Email / Database
Enter fullscreen mode Exit fullscreen mode

The HTTP Request node can send the file to Claix with the schema ID and API key.

Once the response comes back, the rest of the workflow works with structured fields instead of trying to interpret the original document again.

For a simple invoice workflow, the comparison node might receive:

{
  "invoice_number": "INV-2026-00456",
  "supplier_name": "Acme Supplies Ltd",
  "total_amount": 1284.5,
  "purchase_order_total": 1200,
  "difference": 84.5,
  "difference_percentage": 7.04
}
Enter fullscreen mode Exit fullscreen mode

The AI agent does not need to rediscover the invoice total.

It can focus on the actual decision:

The invoice is 7.04% above the purchase order. Request human approval.
Enter fullscreen mode Exit fullscreen mode

That is a much better use of an agent.

Structured extraction is not the same as simple OCR

OCR is useful, but OCR alone does not solve the full workflow problem.

OCR answers a question like:

What text appears in this image?
Enter fullscreen mode Exit fullscreen mode

A business workflow usually needs something more specific:

Which value is the invoice total?
Which date is the issue date?
Which company is the supplier?
Is this document a valid invoice?
Does the total match the purchase order?
Enter fullscreen mode Exit fullscreen mode

The layout and meaning matter.

A document can contain several numbers that look like totals:

  • Subtotal
  • Taxable base
  • VAT
  • Discount
  • Amount paid
  • Amount due
  • Grand total

Extracting text is only the beginning. The workflow needs fields with business meaning.

That is why a schema is useful. It describes not just the type of output, but what each field represents.

Handling missing information safely

One of the most important properties of an extraction workflow is how it handles missing data.

If a field is not present in the document, the system should not invent a plausible value just to fill the schema.

For example, if an invoice does not show a due date, the correct result is:

{
  "due_date": null
}
Enter fullscreen mode Exit fullscreen mode

Not:

{
  "due_date": "2026-04-14"
}
Enter fullscreen mode Exit fullscreen mode

A missing value is different from an inferred value.

That distinction matters in finance, legal workflows, compliance, procurement, and customer operations.

A downstream workflow can then explicitly decide what to do:

if (invoice.due_date === null) {
  return "manual_review";
}
Enter fullscreen mode Exit fullscreen mode

This is more reliable than allowing a model to generate a date based on common payment terms.

Agent Mode for semantic business logic

Structured extraction is useful when you need explicit fields.

Sometimes the workflow also needs semantic evaluation.

For example:

  • Does the contract contain an automatic renewal clause?
  • Is the cancellation penalty present?
  • Is the invoice subject to a special tax rule?
  • Does this document satisfy the internal procurement policy?
  • Is the customer eligible for a particular process?
  • Is the image legible enough to approve automatically?

Claix supports an Agent Mode in which the schema includes an agent definition.

The first phase extracts the structured data.

The second phase evaluates defined business questions and returns typed values.

A response can include both:

{
  "success": true,
  "schema_utilizado": "Contract Review",
  "total_registros": 1,
  "data": [
    {
      "tenant_name": "Example Company",
      "monthly_rent": 950
    }
  ],
  "agent_data": {
    "has_automatic_renewal": false,
    "has_penalty_clause": true,
    "contract_type": "fixed_term",
    "requires_manual_review": false
  }
}
Enter fullscreen mode Exit fullscreen mode

The difference between a general chat response and this type of workflow is that the agent outputs are designed to be consumed by software.

A boolean can trigger a branch.

An enum can select a path.

An integer can drive a calculation.

A string can be stored in a database or included in a generated response.

Document context and queryable memory

Not every workflow should send the same document to the model repeatedly.

If an agent needs to ask several questions about a document over time, the system can persist the processed document context and query it when necessary.

This creates a separation between:

  • Short-term agent context
  • Structured operational fields
  • Long-term document context
  • User or account memory

These are not always the same thing.

A conversational summary is not a reliable replacement for a contract.

A vector database is not always the best place for a field like contract_end_date.

A structured field is not always enough to answer a nuanced question about a clause.

Different information needs different storage and retrieval strategies.

With Claix’s document context flow, an extraction can return a document_id. That identifier can later be used to:

  • Retrieve the stored document content
  • Ask targeted questions about the document
  • Delete the persisted document when it is no longer needed

A question request can look like this:

{
  "questions": [
    "What is the exact early termination penalty?",
    "Does the contract renew automatically?",
    "Who is responsible for maintenance?"
  ]
}
Enter fullscreen mode Exit fullscreen mode

The response preserves the relationship between each question and its answer:

{
  "user_ask": [
    "What is the exact early termination penalty?",
    "Does the contract renew automatically?",
    "Who is responsible for maintenance?"
  ],
  "ia_response": [
    "The penalty is one month's rent.",
    "No, the contract does not renew automatically.",
    "The tenant is responsible for ordinary maintenance."
  ]
}
Enter fullscreen mode Exit fullscreen mode

This allows the main agent to retrieve only the information it needs instead of carrying the entire document through every turn.

Knowledge Spaces for multiple documents

Many business questions cannot be answered from one document.

Examples include:

  • Compare a contract with a supplier invoice.
  • Check whether several invoices match a purchase order.
  • Find which vendor has the highest total across a folder.
  • Compare versions of a policy.
  • Consolidate data from multiple reports.
  • Cross-reference a proposal with a pricing spreadsheet.

For these cases, documents can be grouped into a shared knowledge space.

The workflow can:

  1. Create a space.
  2. Process documents with context enabled.
  3. Associate each document with the space.
  4. Ask questions across the space.

The question can be something like:

Which invoice does not match the pricing terms in the contract?
Enter fullscreen mode Exit fullscreen mode

Or:

What is the total amount billed by each supplier across all current invoices?
Enter fullscreen mode Exit fullscreen mode

Instead of manually loading every file into an agent prompt, the system can use a scoped set of documents.

This helps keep the main workflow focused and gives the document layer responsibility for locating relevant information.

Where this fits in an agent architecture

Claix is not intended to replace the entire agent stack.

It is better understood as a specialist tool or document agent.

A general-purpose orchestrator can decide:

This task involves a PDF invoice. Delegate extraction to the document tool.
Enter fullscreen mode Exit fullscreen mode

Claix returns structured data.

The orchestrator then decides what to do next:

The invoice total differs from the purchase order. Ask for approval.
Enter fullscreen mode Exit fullscreen mode

This produces a clean division:

Orchestrator:
Planning, routing, decisions, tool selection

Claix:
Document ingestion, extraction, normalization, document context

Business system:
CRM, ERP, database, spreadsheet, email, notifications
Enter fullscreen mode Exit fullscreen mode

This pattern also maps naturally to multi-agent architectures.

A document-processing agent can expose capabilities such as:

  • Extract data from a file using a schema
  • Query a persisted document
  • Ask questions across a knowledge space
  • Return typed semantic evaluations

The main agent does not need to understand how OCR, document parsing, or extraction works internally.

It only needs to know when to use the capability and how to consume the result.

A practical example: contract and invoice reconciliation

Consider a procurement workflow.

The company receives:

  • A supplier contract in PDF
  • A monthly invoice in PDF
  • A pricing spreadsheet
  • A purchase order from the ERP

The workflow needs to determine whether the invoice should be approved.

A fragile implementation might send everything to one agent:

Read these documents and tell me whether the invoice is correct.
Enter fullscreen mode Exit fullscreen mode

A more controlled implementation would look like this:

Step 1: Extract the contract

{
  "supplier_name": "Acme Supplies Ltd",
  "contract_currency": "EUR",
  "payment_terms_days": 30,
  "contracted_monthly_amount": 1200,
  "has_price_escalation_clause": true
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Extract the invoice

{
  "invoice_number": "INV-2026-00456",
  "supplier_name": "Acme Supplies Ltd",
  "invoice_date": "2026-03-14",
  "total_amount": 1284.5,
  "currency": "EUR"
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Retrieve the relevant pricing rule

The agent asks the document context:

What price escalation is permitted for March 2026?
Enter fullscreen mode Exit fullscreen mode

Step 4: Apply the business rule

The workflow calculates the allowed amount and compares it with the invoice.

Step 5: Decide

The invoice is 7.04% above the purchase order. The contract allows a maximum increase of 3%. Route to manual review.
Enter fullscreen mode Exit fullscreen mode

The agent is still useful.

It simply is not forced to perform every task at once.

Claix and the A2A direction

As agent systems become more modular, specialized capabilities need to be discoverable and callable by other agents.

A document agent can be useful in an Agent2Agent architecture because it offers a focused capability:

I can process business documents and return structured, queryable information.
Enter fullscreen mode Exit fullscreen mode

An orchestrator might delegate a task such as:

Extract the supplier, total, currency, and payment terms from this invoice.
Enter fullscreen mode Exit fullscreen mode

Or:

Compare the current invoice against the contract and report any mismatch.
Enter fullscreen mode Exit fullscreen mode

The document agent handles the file-specific work and returns a machine-readable result.

This is preferable to giving every agent direct access to every document and expecting each one to build its own parsing strategy.

Specialization can improve:

  • Security boundaries
  • Permission management
  • Cost control
  • Observability
  • Reusability
  • Testing
  • Error handling

It also means a document-processing capability can be reused across different orchestrators and applications.

Using Claix from Python

A basic request can be made with requests:

import requests

url = "[https://claix.dev/api/pdf-json](https://claix.dev/api/pdf-json)"

headers = {
    "x-api-key": "YOUR_API_KEY"
}

data = {
    "schema_id": "3c7a9f21-4b8e-4d1a-9c6f-2e0d8a5b7c4f"
}

with open("invoice.pdf", "rb") as file:
    files = {
        "file": ("invoice.pdf", file, "application/pdf")
    }

    response = requests.post(
        url,
        headers=headers,
        data=data,
        files=files
    )

response.raise_for_status()

result = response.json()

invoice = result["data"]

print(invoice["invoice_number"])
print(invoice["total_amount"])
Enter fullscreen mode Exit fullscreen mode

For Agent Mode:

import requests

url = "[https://claix.dev/agent/pdf-json](https://claix.dev/agent/pdf-json)"

headers = {
    "x-api-key": "YOUR_API_KEY"
}

data = {
    "schema_id": "b980cfe7-61ef-4a5a-9724-881c8a5541e2"
}

with open("contract.pdf", "rb") as file:
    files = {
        "file": ("contract.pdf", file, "application/pdf")
    }

    response = requests.post(
        url,
        headers=headers,
        data=data,
        files=files
    )

response.raise_for_status()

result = response.json()

structured_data = result["data"]
agent_data = result["agent_data"]

print(structured_data)
print(agent_data)
Enter fullscreen mode Exit fullscreen mode

The same API pattern can be used from Node.js, n8n, Make, Zapier, or a custom backend.

When to use Claix instead of building everything yourself

Building your own document pipeline can be a good choice.

For a small number of known document formats, local processing with tools such as PDF parsers, OCR libraries, spreadsheet libraries, and an LLM may be sufficient.

A managed document API becomes more interesting when:

  • Documents come from different customers.
  • Formats change frequently.
  • You need PDF and image support.
  • You need consistent schema-based outputs.
  • You want to connect the workflow quickly through HTTP.
  • You need document context beyond a single request.
  • You want to compare multiple documents.
  • You need Agent Mode for semantic fields.
  • You would rather focus on the business workflow than maintain parsers.

The choice depends on your requirements around privacy, latency, cost, control, and operational ownership.

Claix is designed for teams that need the document layer to be accessible through an API rather than rebuilding it for every workflow.

Designing reliable document automations

A few practical rules make a significant difference.

Keep the schema focused

Do not request every possible field if the workflow only needs five.

A smaller schema is easier to validate and easier to debug.

Separate extraction from decisions

First extract the facts.

Then apply business logic.

This makes it easier to understand whether a failure came from document interpretation or from the rule itself.

Treat missing values explicitly

A missing field should remain missing.

Use null, confidence checks, or a manual-review branch instead of silently guessing.

Preserve source context

For important decisions, keep the relationship between an output field and its source document.

This is particularly important for compliance, finance, contracts, and healthcare workflows.

Add deterministic checks

Use normal code for things that normal code handles well:

  • Date comparisons
  • Arithmetic
  • Thresholds
  • Required fields
  • Enum validation
  • Duplicate detection
  • Database lookups

The model can interpret the document. It does not need to perform every deterministic operation.

Add a human review path

Not every document should be processed automatically.

Unreadable scans, conflicting totals, missing signatures, and ambiguous clauses should be routed for review.

A reliable workflow is not one that never asks a human for help.

It is one that knows when it should.

The bigger idea

The future of AI automation is probably not one giant agent that receives every file, has every tool, and makes every decision.

A more practical pattern is composable specialization:

Input agent
   ↓
Document extraction agent
   ↓
Validation layer
   ↓
Reasoning agent
   ↓
Business system
   ↓
Human approval when necessary
Enter fullscreen mode Exit fullscreen mode

Each component has a clear responsibility.

The document layer converts messy files into structured, queryable information.

The reasoning layer interprets that information.

The workflow layer applies rules and triggers actions.

The human remains in control of high-impact decisions.

That architecture is easier to debug than a single autonomous loop because you can inspect each boundary.

When a workflow fails, you can ask:

  • Was the document unreadable?
  • Was the schema wrong?
  • Was a field missing?
  • Did validation reject the result?
  • Did the business rule calculate incorrectly?
  • Did the agent misunderstand an already-structured value?

That is much more useful than simply knowing that “the agent produced the wrong answer.”

Final thoughts

AI models are becoming increasingly capable at reasoning over complex information.

But capability is not the same as reliability.

If your workflow depends on invoices, contracts, spreadsheets, reports, forms, or scanned documents, the quality of your document layer will often matter more than the complexity of your agent framework.

Claix is built around a straightforward idea:

Documents should become structured, validated, and queryable before they become agent context.

Once that happens, agents have less irrelevant information to process, workflows can rely on stable fields, and developers can use AI for the parts that genuinely require reasoning.

Instead of asking an agent to do everything, give it a clean input and a well-defined job.

That is where agent automation starts becoming useful in production.

Top comments (0)