Linnk AI Logo
← All Research

Document Translation for AI Agents (2026): Why File-In, File-Out Beats Putting the PDF in Context

By Linnk Research Team | August 2026 | 11 min read

Key Takeaways

  • Putting a document in an agent's context costs far more than it looks. Anthropic documents PDF text at 1,500–3,000 tokens per page, and because every page is also rendered to an image, you pay visual tokens on top — capped at 1,568 per page on standard models, 4,784 on high-resolution ones. A 60-page contract runs roughly 184k–467k tokens just to read, and it is re-sent on every turn.
  • Cost is the smaller problem. The structural problem is asymmetry: a language model can read a document and structurally cannot write one. Claude's own documentation states it "cannot generate, produce, edit, manipulate, or create images." No prompt produces a laid-out PDF.
  • PDFs aren't text. They're positioned glyphs on a canvas. Reading order in a two-column paper is inferred, not parsed, and it fails silently — you get fluent translated prose in the wrong order, with no error.
  • The pattern that resolves both is file-in, file-out: the agent orchestrates, a document service does the document work, and the file's contents never enter the context window. The agent handles a path and a one-line JSON receipt.
  • It is not always the right call. If you want the text — a summary, an extraction, a RAG chunk — context is exactly where it belongs. Delegate when the artifact is the deliverable; keep it in context when the content is.

The Task Looks Trivial Until You Watch the Token Counter

You're in a session with Claude Code, Cowork, Codex, OpenClaw, or Hermes. The request is mundane: translate this vendor contract into German and put it in ./out. Sixty pages. You expect one tool call.

What you get back is a Markdown file. The tables have been flattened into pipe-delimited approximations or dissolved into paragraphs. Footnotes have migrated into the body. The signature block is a row of stray characters. Everything that made the file a contract rather than a text dump is missing from the output because it was never in the input. And the usage counter moved a lot more than you expected.

The instinct is to blame the model. That's the wrong diagnosis — it did the job with the only tools it had. The problem is architectural, and once it's visible the fix is obvious and slightly boring: the document should never have entered the conversation at all.

This is a field report on why agents struggle with documents, what the numbers actually are, and the file-in/file-out pattern that agent-shaped tooling converged on during 2026. Every claim about cost is sourced to vendor documentation; every claim about tooling is checked against a shipped release rather than a spec, because the two disagree more often than anyone would like.

What a Document Actually Costs in Context

Start with arithmetic, because it's worse than most people's intuition.

Anthropic documents the PDF pipeline explicitly: when you send a PDF, "the system converts each page of the document into an image," and "the text from each page is extracted and provided alongside each page's image." You are billed for both. Documented text cost is 1,500–3,000 tokens per page depending on content density.

The image half follows the vision rules. Claude "views images in patches instead of pixels," each patch a 28×28-pixel block, so an image costs ⌈width / 28⌉ × ⌈height / 28⌉ visual tokens. Each tier then caps that:

Resolution tier Models Max long edge Max visual tokens
Standard Everything else 1568 px 1568
High-resolution Claude 4.7 and later 2576 px 4784

Note the standard tier caps at 1,568 visual tokens per image — a full page hits that ceiling and stops. So one page of a dense PDF costs roughly 3,000–4,600 tokens on a standard-tier model, and up to 7,800 on a high-resolution one, where the visual half can run to 4,784.

Document Standard tier High-resolution tier
10-page report ~31k–46k ~42k–78k
60-page contract ~184k–274k ~252k–467k
100-page filing ~306k–456k ~420k–778k
300-page manual over the per-request page ceiling over the per-request page ceiling

The table simplifies — density varies, and a sparse deck costs far less than a dense filing. The shape is what matters, and the shape holds at either end of the range.

Two consequences follow. First, ceilings are real: Anthropic caps requests at 100 PDF pages when the context window is under 1M tokens, 600 above it. A 300-page manual isn't a budget question, it's a rejected request. Second, even where it fits, you've spent 40–75% of a million-token window on raw input before the agent produces a single translated sentence. Your instructions, the agent's reasoning, tool results, and the output all compete for what's left.

And you pay it repeatedly. As the docs note about multi-turn workflows, "each request resends the full conversation history." A document parked in context isn't a one-time charge — it's rent, collected every turn.

One more constraint catches people at the worst possible moment: password-protected PDFs are out entirely. The documented requirement is "standard PDF (no passwords/encryption)" — and encrypted files are routine in exactly the categories where translation matters most, like legal bundles and financial filings.

Reading Is Expensive; Writing Is Impossible

If cost were the only issue you could throw a bigger window at it. The deeper problem is that the round trip isn't symmetrical.

Reading a PDF is a reconstruction problem. A PDF doesn't store text in reading order — it stores positioned glyphs, instructions for painting characters at coordinates. There's no marker saying "column two starts here." Reading order in a two-column journal page, a table, or a sidebar has to be inferred, and different extractors infer differently. The failure is quiet: extraction succeeds, emits plausible text, and the order is wrong. Your agent then translates that scrambled text fluently and confidently. You get grammatical German saying things the source never said, in an order it never used. Nothing errors. Nothing warns you. This is worse than a crash, because a crash is visible.

Writing a document is not a problem the model can solve at all. This is the part that surprises people. Claude's vision documentation states the constraint plainly: it "is an image understanding model only. It can interpret and analyze images, but it cannot generate, produce, edit, manipulate, or create images." A language model emits tokens. It cannot emit a rendered page, a .docx with the original styles applied, a .pptx with the master layout intact, or a PDF where the table is still a table.

An agent can of course script its way toward a file — call python-docx, write some XML, shell out to LibreOffice. Agents do this, and for simple documents it works. It degrades fast on real ones. Preserving a master slide layout, a multi-level numbered list with its numbering context, a footnote anchored to its reference, an equation's math run, or a table's merged cells means round-tripping the original file's internal structure — not regenerating a lookalike from a text description. Each of those is a specialist problem people have spent careers on.

So, honestly stated: your agent reads documents expensively and imperfectly, and cannot write them back. Both halves of "translate this contract" work against it.

The File-In, File-Out Pattern

The fix is a boundary. The agent keeps what it's good at — understanding intent, choosing the target language, deciding what happens to the result, running the workflow around the document. A document service keeps what it's good at — parsing the file's real structure, translating, and rendering an output file that preserves layout.

Critically, the document's contents never cross into the agent's context. The agent sends a path and receives a path. What flows through the conversation is a filename, a language code, a status, and a cost — dozens of tokens, not hundreds of thousands.

agent                         document service
  |                                  |
  |--- translate(file, --to de) ---->|
  |                                  |  parse real structure
  |                                  |  translate
  |                                  |  render output file
  |<-- {"status":"success",          |
  |     "output_file":"..."} --------|
  |
  context cost: a path and a receipt

This is the same instinct behind every other tool an agent uses. You don't paste a database into context to run a query — you run the query and read the rows. You don't load a video into context to trim it — you call ffmpeg. Documents got treated differently only because models can read them: well enough to be tempting, not well enough to be right.

There's a second-order benefit that matters more than it sounds: determinism. An agent translating from context produces a different result every run. A document service given the same file and target produces the same artifact. When the output is a deliverable rather than a draft, that difference is the whole ballgame.

Delegating vs. Doing: An Honest Comparison

Agent does it in context File-in / file-out service
Context cost ~3k–7.8k tokens per page, re-sent every turn A path and a status line
Page ceiling 100 pages/request under 1M context Bounded by the service, not the window
Encrypted PDFs Rejected — "no passwords/encryption" Handled if the service supports it
Output format Markdown or plain text The original format back
Layout, tables, formulas Lost or approximated Preserved by design
Scanned pages Vision read; no way to render back OCR in, laid-out file out
Reproducibility Varies per run Same input, same artifact
Failure mode Silent — wrong order, fluent output Explicit — exit code and error string
What the agent is doing Being a document parser, badly Orchestrating, which is its job
Good for Summaries, extraction, Q&A, RAG Deliverables someone will open

The last two rows are the ones worth internalizing. This isn't "agents are bad at documents" — it's a division of labor. Ask what does this contract say about termination and context is exactly right: you want the text, and you want the model reasoning over it. Ask for the contract in German that I can send to counsel and you want an artifact, which is a different job with different machinery.

What an Agent-Shaped CLI Actually Looks Like

Concretely, using the Linnk CLI — one implementation of this pattern, built for agent invocation rather than adapted to it. The canonical form:

npx -y @getlinnk/cli translate contract.pdf --to de --out ./out/contract.de.pdf

File in, translated file out. It takes PDF, DOCX, XLSX, PPTX and images, and returns the same format with layout, tables and formulas preserved. Scanned pages route through OCR instead of failing. --from sets the source language and defaults to auto-detect; --pages N translates only the first N pages, which is the documented lever for sampling a long document before committing to it.

Three design details are worth pulling out, because they're what separate a CLI an agent can actually drive from one a human merely tolerates:

The output is one line of JSON. Success returns {"schema":"v1","status":"success","output_file":"/abs/path…","preview_url":"…"}. Errors return {"schema":"v1","status":"error","code":"E_*","message":"…","help":"…"} — where help states the fix in a form the agent can act on. Machine mode auto-enables when stdout is piped. An agent doesn't have to scrape human prose to find out what happened.

Exit codes are typed, not binary. 0 ok, 2 usage, 3 auth, 4 quota, 5 file, 6 job failed, 7 timeout. That distinction matters because the recovery differs: an agent should retry a timeout, escalate an auth failure to the user, and neither retry nor escalate a usage error — it should fix its own command.

There's a recovery path for the quota wall. When a run returns E_QUOTA_EXCEEDED, npx -y @getlinnk/cli connect signs the user in, opens checkout for a free account, and waits until payment lands. One command instead of a dead end that leaves the agent guessing. This matters more than it sounds: the alternative is an agent that hits a wall and quietly falls back to reading the PDF itself — producing exactly the flattened output the tool existed to prevent.

There's also a small piece of engineering judgment worth citing, because it's the kind of thing that separates a real tool from a demo. The CLI classifies scanned-vs-digital locally before uploading, and the classifier is deliberately asymmetric: it returns "digital" only on positive evidence, and lets uncertainty fall through to OCR. The reasoning, from the source comment: a scan misrouted to digital translation produces nothing at all, so the tool never risks failing a translation to save credits. Scanned pages cost more; producing an empty file costs more still.

Wiring It Into Your Agent

The reason a CLI is the right shape is that every major agent already knows how to run one. There's no integration to build, no MCP server to host, no protocol handshake. The agent needs to know the tool exists and when to reach for it.

The lowest-friction path is a fetchable install doc at linnk.ai/linnk-agent-install.md. Point your agent at that URL and ask it to install the skill; it writes the skill file to whichever location its own runtime loads:

  • Claude Code~/.claude/skills/linnk-translate/SKILL.md
  • Cursor.cursor/rules/linnk-translate.mdc
  • Codex / Gemini CLI / other → appended to AGENTS.md in the project

For agents outside that list, the same content works. Claude Cowork is arguably the most natural fit of the whole category, since Cowork is aimed at knowledge work on local files — its users are the ones with contract bundles and decks rather than repositories. OpenClaw users will want it as a ClawHub skill, which is a thin wrapper over one command. Hermes Agent distills successful task paths into reusable skill documents, so the durable win is getting the first run right and letting the skill persist — be explicit about the file-in/file-out contract on that run, or Hermes may distill the wrong path, the one where it read the PDF itself.

If you'd rather write the instruction yourself, state the boundary rather than the mechanics. The skill's own description does exactly this: use it "when the user asks to translate a file/document and the formatting matters… or when extracting text and re-translating would break tables, formulas, or typesetting," and explicitly don't use it for plain text or code snippets. Telling an agent why generalizes; telling it a memorized invocation doesn't.

One deployment note that catches teams: on a CI runner or a remote box there's no browser to complete a login flow. Set LINNK_API_KEY as an environment variable and the interactive path never triggers. It's the difference between a tool that works in your terminal and one that works in your pipeline.

The Cost Model, Without the Marketing

Agent-shaped tools live or die on whether cost is predictable. An agent that can't predict spend will either over-spend or refuse to act, and both are bad.

The credit model is a flat weighting, and it's small enough to state completely:

Unit Credits
Digital page 1
Scanned / OCR page 4
Image 4
PowerPoint 1 per slide

Scanned pages cost 4× because OCR plus layout reconstruction is genuinely more compute — worth knowing before you point an agent at a bundle of scans and extrapolate the bill from a clean DOCX. Plans run $10/month for 750 credits, $20 for 1,500, and $40 for 3,000, at the same flat rate per credit at every tier, so there's no volume-discount math to reason about. Yearly billing is 20% off — displayed as $8/$16/$32 per month — granted monthly rather than as an annual lump, with unused credits rolling over for two months. In page terms, 750 credits is roughly 750 digital pages or about 185 scanned ones.

Two honest caveats, because a cost section that only flatters the tool isn't useful:

The marketing says your agent sees the exact cost before a job runs. As of v0.5.2 that isn't quite true. The formula is deterministic and every input to it — page count, scanned-vs-digital classification, format weight — is computed locally before upload. But there's no inspect command and no --dry-run, so nothing prints an estimate. credits_charged and remaining balance come back after the job. The practical mitigation is --pages N on an unfamiliar document. An internal design review flagged this same gap, which is the reason to trust the shipped behavior over the pitch.

Agent credits are separate from a Linnk website subscription. Paying for translations on linnk.ai does not include agent credits, and linking an account is attribution-only — it grants nothing. They're distinct meters for distinct channels. The pricing page says so, but it still surprises people.

The trial is one document up to 20 pages, no signup and no API key — which matters for agent workflows specifically, because it means an agent can finish a real task on the first attempt without stopping to ask you for a credential. Note that a document over 20 pages is rejected rather than silently truncated; the error suggests re-running with --pages 20 to translate the first 20 free. Rejecting is the right call — a half-translated contract that looks complete is worse than a clear refusal — but it surprises people who expected truncation.

When You Shouldn't Delegate

A pattern is only credible with its exclusions. Don't route through a document service when:

  • You want the text, not the document. Summarization, clause extraction, Q&A, RAG indexing, "does this mention indemnity" — all of these want content in the model's context. That is what a context window is for.
  • The source is already plain. Markdown, .txt, code strings, JSON locale files. No layout to preserve means nothing to protect; the round trip buys you nothing. The skill's own instructions say to handle these directly.
  • The translation has to stay in the loop. If the agent must reason over the translated text — comparing clauses across languages, checking terminology consistency — it needs it in context anyway. Delegating hands you a file the agent then has to read back, which is the worst of both.
  • It's a one-paragraph clipping. Paste it. The overhead isn't worth it.
  • You need to run it yourself. If self-hosting is a hard requirement, BabelDOC (open source, on PyPI) does layout-aware PDF translation locally — it detects page layout, extracts text with coordinates, translates, and re-renders into the original positions. It's PDF-only and you operate it, but for a self-hosted pipeline it's the honest recommendation.
  • You're already integrated with a translation API. Both major ones do documents properly, and this is worth being precise about because it's often described wrongly. DeepL has a document endpoint (/v2/document) taking .docx, .pptx, .pdf, .html and .xlf, preserving fonts, tables, footnotes and paragraph numbering. Google Cloud Translation Advanced has translateDocument for PDF and DOCX, likewise preserving layout. If you already hold a key for either, you already have layout-preserving document translation — use it. The distinction that matters for this article isn't capability, it's invocation: those are APIs you integrate against, whereas an agent that can run a shell command can use a CLI with no integration at all. The other real difference is scanned input — DeepL's PDF layout retention depends on the text being selectable, so image-only pages are where the approaches genuinely diverge.

Also worth knowing what this class of tool doesn't do yet. Glossary and style-instruction flags are specified but not shipped in v0.5.2 — if you need enforced terminology today, that's a gap, and a spec document promising it isn't the same as a release providing it.

The through-line: delegate when the artifact is the deliverable, keep it in context when the content is.

<!-- linnk:faq -->

Frequently Asked Questions

Can Claude Code or Cursor translate a PDF directly?

They can read one and produce translated text, but not a translated document. The model emits Markdown or plain text; it cannot render a PDF or write a .docx with the original styles applied — Claude's documentation states it "cannot generate, produce, edit, manipulate, or create images." If you need a translation to reason over, direct reading is fine. If you need a file to send to someone, you need a document service.

How many tokens does a PDF actually use in an agent's context?

Anthropic documents 1,500–3,000 text tokens per page, plus visual tokens for every page because each page is also converted to an image. Those are capped per tier: 1,568 visual tokens per image on standard models, 4,784 on high-resolution ones (Claude 4.7 and later). That puts a dense page at roughly 3,000–4,600 tokens on a standard tier and up to 7,800 on high-resolution — so a 60-page contract runs about 184k–467k tokens just to read, and it is re-sent on every conversation turn.

Why does my agent's translated output lose tables and formatting?

Because the formatting was never in the input. PDFs store positioned glyphs rather than structured text, so extraction flattens tables, footnotes, and multi-column flow before the model sees them. The model translates what it received. Preserving structure means round-tripping the original file's internal format, which is a document-processing job rather than a language-model one.

Can an AI agent translate a scanned PDF?

It can read one via vision and give you translated text. It cannot give you back a scanned-layout document, because it cannot render pages. A service with OCR plus layout reconstruction takes the scan in and returns a laid-out file. This is where the gap between "the agent can read it" and "the agent can deliver it" is widest.

Do I need an API key to let my agent translate a document?

Not for the first one — the trial covers one document up to 20 pages with no signup and no key, so an agent can complete a task without pausing to ask for credentials. Beyond that, set LINNK_API_KEY as an environment variable, which is also what makes it work on CI runners and remote machines where there's no browser for an interactive login.

Is this an MCP server?

No — it's a CLI, deliberately. Every agent that can run a shell command can use it with no integration, server process, or protocol handshake. For this shape of task — one command, a file in, a file out — a CLI is a smaller surface than an MCP server and works in more places, including CI.

How should an agent handle running out of credits mid-task?

Check the exit code and the error code rather than the prose. E_QUOTA_EXCEEDED (exit 4) has a defined recovery: npx -y @getlinnk/cli connect signs the user in, opens checkout for a free account, and waits until payment lands, after which the agent retries once. The failure mode to design against is an agent that hits the wall and silently falls back to reading the file itself — which produces exactly the flattened output the tool exists to prevent.

What formats does agent document translation support?

The Linnk CLI takes PDF, DOCX, XLSX, PPTX and images, returning the same format with layout, tables and formulas preserved. For plain formats — Markdown, .txt, JSON locale files — you don't need a document service at all; there's no layout to protect and an agent handles those natively.

Should I use a document service or just do it in the agent?

Delegate when the artifact is the deliverable — something a person will open, where layout carries meaning. Keep it in context when the content is what you need: summarization, extraction, Q&A, or anything where the agent must reason over the translated text. The two aren't competing; they answer different questions. <!-- /linnk:faq -->

Bottom line. Agents are good at orchestration and bad at document I/O, and the gap is structural rather than a prompting failure — reading a document costs thousands of tokens per page and loses the structure anyway, while writing one back is something a language model fundamentally cannot do. The pattern that works is a boundary: the agent handles a path and a receipt, a document service handles the document. Use it when the artifact is the deliverable, skip it when you genuinely want the text in context, and be honest with yourself about which one you're doing.

Resources

  • Scanned Document Translation in 2026: From OCR Pipelines to Layout-Aware AI — the upstream problem when your source is a scan rather than a born-digital file.
  • Long-Document AI Summarization: How It Actually Works (2026) — the companion case, for when you want content in context rather than an artifact out of it.
  • Cross-Language Research Workflows in 2026 — the human workflow this pattern sits inside.

Written by the Linnk Research team — we translate, summarize, and read documents for a living, including from inside agent sessions.