Skip to content
Back to Portfolio
ArticleRead time: 4 min

The Machine-Readable Engineer: How I Optimized My Portfolio for AI Agents and ATS

By Kaio Vítor Morsch

For years, we have built the web for human eyes. We argued over pixel-perfect layouts, CSS animations, and optimal font sizes. But the landscape of recruitment and information discovery has shifted. Today, the first visitor to your portfolio is rarely a hiring manager — it is an Applicant Tracking System (ATS), an AI crawler, or an automated sourcing agent.

If your portfolio relies solely on standard HTML tags to convey your experience, you are playing a risky game of chance with parsing algorithms. I decided to stop guessing and start explicitly communicating with the machines. Here is how I optimized my portfolio to be fully machine-readable.

01 // Schema Injection

Stop Guessing, Start Declaring: The Power of JSON-LD

When an AI agent or an older ATS parses a webpage, relying on DOM structure is a gamble. Does that h3 represent a job title or a project name?

To eliminate parsing errors and hallucinations, I bypassed HTML scraping entirely by implementing strict Schema.org markup using JSON-LD via my useSchemaOrgProfile composable. Instead of letting the bot scrape my UI, I feed it a structured Person object. My tech stack goes explicitly into the knowsAbout array, my employment history into worksFor, and my educational background into alumniOf.

json-ld
{
  "@context": "https://schema.org",
  "@type": "Person",
  "name": "Kaio Vítor Morsch",
  "jobTitle": "Senior Software Engineer",
  "knowsAbout": [
    "Go", "Vue.js", "Distributed Systems",
    "Payment Gateways", "Microservices"
  ],
  "worksFor": {
    "@type": "Organization",
    "name": "DOT Digital Group"
  },
  "alumniOf": {
    "@type": "CollegeOrUniversity",
    "name": "Unicarioca"
  }
}
02 // Crawling Policy

Opening the Doors: A Permissive robots.txt

AI accessibility starts at the front door. Recently, there has been a trend of developers blocking AI crawlers to save bandwidth or protect content.

For a professional portfolio, this is counterproductive. My robots.txt is intentionally permissive (User-Agent: * with no disallow rules). If an automated recruiter agent is trying to summarize my background for a tech lead, I want to ensure it has unrestricted access to index my entire professional history.

robots.txt
User-agent: *
Allow: /

# AI crawlers welcome
# Recruiter bots: index everything
03 // Global Context

Global Context: Metadata and Native i18n

LLMs operate globally, and so does the job market. Serving an AI agent the right context instantly saves processing time and ensures accuracy.

Through my application configuration, I structured clean metadata to establish immediate context. Furthermore, my internationalization strategy is built to serve bots the correct language natively. If a US-based recruiter uses an AI tool to source candidates, the bot is not forced to dynamically translate a page and risk losing technical jargon — it accesses the English localization directly.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      htmlAttrs: { lang: "en" },
      meta: [
        { name: "description", content: "Senior Software Engineer..." }
      ]
    }
  },
  i18n: {
    strategy: "no_prefix",
    locales: [
      { code: "pt", name: "Portuguese" },
      { code: "en", name: "English" },
      { code: "ja", name: "Japanese" }
    ]
  }
})
04 // Synthesis

Building for the New Web

In the era of Generative AI, our target audience is no longer just humans browsing our sites. We are developing for intelligent agents that crawl, summarize, and evaluate our profiles at scale.

By combining permissive crawling, semantic metadata, and strict JSON-LD schemas, we ensure that our data is exactly where the bot expects it to be. The future of the web is machine-readable, and as engineers, our personal infrastructure should reflect that reality.

Want to read more articles?

Back to Portfolio