Building for humans and agents
jul 2026 · 2 min read
This is a site note, not a research writeup. I keep those separate on purpose — the real work lives in the ProjectDiscovery blog and the talk queue. This is just the "how this thing is built" page, the kind every personal site used to have before colophons went out of style.
Here's the premise: this site has two audiences, and they don't read the same format.
People skim. They want typography, whitespace, a scannable hierarchy — something they can size up in a few seconds before deciding whether to actually read a paragraph. Agents don't skim. They parse. Handing an agent a fully-styled HTML page and expecting it to extract "what does this page actually say" is asking it to do unnecessary work — strip the nav, ignore the footer, guess which <div> is content. So every page on this site ships twice: once as HTML for the browser, once as plain markdown at the same path with .md appended.
/about → the rendered page, for people
/about.md → the same content, plain markdown, for agents
/agents.md → the manifest: every .md path on the site, one file
Both come from the same source at build time — typed content modules and MDX, rendered once for React and once through a small emitter script that walks the same data and writes markdown. They can't drift apart because there's only one source of truth to drift from. If a page can't be expressed as clean markdown, that's a sign the page is doing too much.
None of this is exotic. llms.txt is an actual (if informal) spec now, and enough tools respect Accept: text/markdown that serving it costs nothing. The interesting part, for me, is a smaller version of a problem I spend my working hours on: knowing what an agent actually did with what you gave it.
At ProjectDiscovery, my day job is building the tracing and evals behind Neo — instrumenting every LLM call and tool call in a run so there's a record of what the model saw, what it decided, and what it did with the result. Benchmarking numbers are only useful if you can also answer "why did it do that on run 41 but not run 12," and that answer lives in the trace, not the score. A behavioral audit is mostly a very disciplined way of reading traces at scale.
Serving agents a clean markdown twin is the same instinct scaled down to a personal site: don't make the consumer reconstruct meaning from a format built for something else. If an agent lands on this page — hi — the honest version of this content is one character away, at /writing/building-for-humans-and-agents.md. Start at /agents.md if you want the whole site instead of one post.
That's it. No framework opinions, no "future of the web" claims. Just a small, load-bearing decision that made the rest of the site easier to reason about — for both readers.