Skip to content
GBAI SpecialistPortuguês — View this site in Portuguese

AI Specialist at iK · São Paulo, Brazil

AI systems
running in production.

Agent orchestration, API integration, telephony, RAG and service desk process automation. The corporate systems below were built at iK; the personal products, outside it. Every card carries its problem, solution, architecture, stack, outcome — and the system’s real status.

Map

ErikaErikaPredikt AlertsPredikt AlertsAD MiddlewareAD MiddlewarePredikt LivePredikt LiveLivePropLivePropMyVibePagesMyVibePagesErika RAGErika RAGPassword reset by phonePassword resetIntelligent QualifierQualifierInternal toolsInternal toolsErikaErikaPredikt AlertsPredikt AlertsAD MiddlewareAD MiddlewarePredikt LivePredikt LiveLivePropLivePropMyVibePagesMyVibePagesErika RAGErika RAGPassword reset by phonePassword resetIntelligent QualifierQualifierInternal toolsInternal tools
Legend: filled disc = system · ring = technical domain · dot = technology or certification · strong line = relation between systemsTap a system to open its card. A line is a declared relation between systems.

Filter by domain

Agents that decide which tool to call, in what order, and when to stop — with a locked scope.

Retrieval over a corporate document base, sweeping every related document before answering.

Voice as an interface: the AI answers, speaks, listens and acts — with no keypad menu.

Layers that talk to corporate systems without exposing credentials or leaking data.

The ticket as the unit of work: open, classify, route, resolve and close.

Detect the incident, attempt self-repair, and only then wake someone up.

Corporate directory actions mediated by a layer that never hands back a credential.

The layer people actually touch — where engineering becomes visible, or invisible.

Erika

Omnichannel service desk orchestrator: answers over chat and phone, and acts directly on the ITSM.

  • In production
  • Corporate system
  • 2026-01

Multi-client service desk operation · Five clients plus the internal operation

Problem

A service desk answers through channels that do not talk to each other. The same request arrives by chat and by phone and gets handled differently, because each channel has its own path into the ticketing system. In the middle of all of them sits an analyst retyping what the user has just said.

Solution

A single orchestrator behind both channels. Erika understands the request in natural language, decides which action to run and talks straight to the ITSM: it opens, queries and updates tickets with no human in between. The channel stops being a fork in the road and becomes just the front door.

Architecture

The orchestration layer receives the intent — chat text or call transcript — and picks which tool to call, in whatever order the flow demands. Actions against the ITSM go through REST APIs. When a request touches identity, Erika does not resolve it herself: she delegates to the AD Middleware, which performs the directory action and returns only the result. Erika never sees a credential.

Diagram — Erika: intent comes in through two channels and leaves as an action in the ITSMReading the diagram: filled box = the system this card describes · outlined box = external system or service · dashed line = asynchronous call.

Connections

Stack

Voice and chat share one decision core instead of each channel carrying its own logic — that is what keeps the two from drifting apart over time. Integration is entirely over REST APIs because every client runs their own ITSM instance, and the contract has to be identical across all of them.

  • LLM
  • REST APIs
  • ITSM
  • Voice
  • Chat
  • Docker
  • Google Cloud

Outcome

Running uninterrupted since January 2026, serving five clients and the internal operation.

~2.000tickets per monthdesde jan/2026 · internal telemetry
24/7in operationdesde jan/2026 · internal telemetry
5clients servedset/2026 · team report

Predikt Alerts

Voice and SMS alerting with intelligent escalation — and a repair attempt before waking anyone up.

  • In production
  • Corporate system
  • 2026

Corporate infrastructure monitoring · Continuous operation, with self-healing live at one client

Problem

An infrastructure alert that lands in an inbox at 3am is not an alert: it is a record for someone to read in the morning. The incident happens overnight, nobody sees it, and the problem stays up until the first shift opens the dashboard. The cost is not in detection — it is in the hours between detecting and anyone finding out.

Solution

Predikt calls. Literally: it reports the incident over the phone and by SMS, and escalates — targeted or broadcast, depending on the rule. Before any of that, though, it tries to fix it: when a service goes down, the system runs the repair action and only escalates if that fails. The overnight gap stopped being a gap.

Architecture

Infrastructure monitoring fires the event. Predikt checks whether a repair action is registered for that symptom and, if so, runs it before sending any notification. If the service comes back, the cycle closes itself. If it does not, the voice-and-SMS escalation chain kicks in and the ticket stays open until the service returns. Either way the ITSM closure is automatic: what closes the ticket is the service coming back, not who fixed it — and the recovery is announced, not merely logged.

Diagram — Predikt Alerts: attempts a repair before waking anyone up

Stack

Voice and SMS rather than email or push because the requirement is not to notify — it is to wake someone. And the automatic ITSM ticket exists for one specific reason: without it, every incident solved by self-healing would vanish from the record, and the system would be invisible precisely when it works.

  • Monitoring
  • ITSM
  • REST APIs
  • Voice
  • SMS
  • Java 21
  • Docker

Outcome

A system I built end to end, running continuously. The real gain is not on a chart: incidents that used to wait for the next morning are now handled the moment they happen.

24/7in operationoperação contínua · internal telemetry
1client with self-healing liveset/2026 · team report
0self-healing failures to datedesde a ativação · internal telemetry

AD Middleware

The layer that performs directory actions for callers that must never hold a credential — and returns only the result.

  • In production
  • Corporate system
  • 2026

Corporate directory in a multi-client operation · A single identity layer, behind a reverse proxy, on a segregated network

Problem

An AI agent that resets a password needs directory permissions. Granting the agent those permissions means placing an administrative credential inside the very process that interprets a user’s free-form text. And the directory is unforgiving: one wrong character in a query is an injection, and an over-privileged service account is the whole incident in a single line.

Solution

No agent talks to the directory. They talk to this middleware over REST, and it translates intent into LDAPS commands. Every operation has a narrow contract: an identifier validated by a regular expression that rejects asterisks, quotes and parentheses; a service account held at least privilege; a response carrying the result and nothing else. The credential never leaves this layer.

Architecture

A Java service on Spring Boot turns REST requests into attribute changes. A password reset, for instance, is one operation seen from outside and three on the inside: it changes the password, clears the account lockout and marks the password as expired to force a new one at next sign-in. Authentication is hybrid — it validates a token issued by the cloud the agents run on, or falls back to a static token when that path is switched off — and is combined with an IP allowlist. There is also a simulation mode that records the intent without touching the directory, which makes it possible to exercise the flow in production with no side effects.

Diagram — AD Middleware: one request from outside, three operations inside

Connections

Stack

Java and Spring Boot because that is where mature LDAP integration lives, and because the protocol has traps only a battle-worn library handles — continuation referrals, for one, break a search unless they are explicitly ignored. The hardening is all edge-and-property: request limiting, strict headers, and every security feature toggled by configuration, so that a penetration test never requires recompiling anything.

  • Java 21
  • Directory
  • REST APIs
  • Docker
  • Google Cloud

Outcome

In production, it is the only path through which Erika acts on identity. The gain is not speed: it is that the agent’s attack surface does not include the directory, and every action performed lands in an audit trail that keeps personal data out of the ordinary log.

Predikt Live

A live incident board that does more than show what broke: it proposes the action and records who decided.

  • Pilot
  • Corporate system
  • 2026

Network operations centre at a managed services provider · Multi-tenant by API key, with one tenant in staging

Problem

An operations dashboard tends to be a mirror: it shows the number and hands the whole question back to the human. Whoever is on call at three in the morning does not need another chart, they need a defensible next action. And whoever reads the same data in the morning, up in management, needs something else entirely — a narrative. One dashboard trying to serve both ends up serving neither.

Solution

Two readings of the same data, in two visual languages: an editorial bulletin for whoever reads it in the morning, and a war-room console for whoever is on call. On top of that, a layer that recommends — and a governance loop where a person accepts or rejects the recommendation, and the record of that decision stays. The AI proposes; it is never in the critical path.

Architecture

Ingestion receives incident openings and closures and correlates the two by ticket number, computing time to repair. It is idempotent by construction: replaying the same event duplicates nothing, and a closure with no matching opening is accepted and flagged as an orphan rather than silently dropped. Every conversation with a language model goes through a single door, and providers are adapters swapped by environment variable — no other file builds an AI request by hand.

Diagram — Predikt Live: correlates by ticket and talks to the model through a single door

Connections

  • consumesErika

    Incidents arrive from Erika’s post-processing, already correlated by ticket

Stack

The single door to the model is what turns swapping providers into a configuration change rather than a refactor: tool declarations live in a neutral schema, and the translation into each vendor’s dialect sits in one file. A relational database because the value here is in correlating events, and correlating is table work, not document work. And the floor under every recommendation is deterministic: the model writes the prose, it does not decide the threshold.

  • Next.js
  • TypeScript
  • LLM
  • Claude
  • Google Cloud
  • Docker

Outcome

The governance-chat milestone shipped and was demonstrated to leadership. What the system proves is not volume: it is that a language model can sit inside a critical operation without becoming a second decision-making door — the recommendation is pulled, never pushed, and what gets recorded is the human acceptance.

LiveProp

Turns raw sales material into a trackable web proposal — and the AI never invents a price.

  • In production
  • Own product
  • 2026

Own product: sales proposals for small sales teams · Multi-tenant SaaS live, with the full flow navigable

Problem

A small team’s proposal starts as a pile: a meeting transcript, a price spreadsheet, an old PDF someone will adapt. The result goes out as an attachment, nobody knows whether it was opened, and the price is retyped by hand every time. Throwing a language model at this fixes the writing and creates a worse problem: a plausible, wrong number inside a document the client will treat as a commitment.

Solution

The model writes and structures, but it does not price. It may only reference an item from the user’s own catalogue, by identifier, or mark the line as pending. Price and margin are computed on the server, afterwards. The proposal becomes a web page with its own link — selectable theme, fixed sections, open events recorded — instead of an attachment that vanishes into an inbox.

Architecture

A Next.js application at the edge, with managed Postgres and row-level isolation keeping each account’s data apart. The generation engine takes text, a transcript or a spreadsheet and returns a structure, not a finished document: the catalogue identifiers come from it, the values come from the table. The public renderer is a route separate from the dashboard, which keeps the page the client opens light and independent of the author’s session.

Diagram — LiveProp: the model picks the catalogue item, the table gives the price

Stack

The rule against inventing a price is not a request inside the prompt: it is an architectural boundary. The model returns an identifier, the server resolves the value — so no prompt improvement and no model swap can reintroduce the error. The default is the cheapest model in the Claude family, because the task is structuring text rather than long reasoning, and prompt caching cuts the cost of the part that repeats on every proposal.

  • Next.js
  • TypeScript
  • Claude
  • LLM
  • Vercel
  • PostgreSQL

Outcome

The whole flow is live and navigable, and the build was frozen as a product decision: a market revalidation showed there was no missing feature that explained the absence of sales — what was missing was distribution. Stopping the code was the deliverable.

97performance score on mobile Lighthouseago/2026 · internal telemetry
0cumulative layout shift (CLS)ago/2026 · internal telemetry
10 msof total blocking time (TBT)ago/2026 · internal telemetry

MyVibePages

A live website platform — and the measured decision that an ad must never land on the home page.

  • In production
  • Own product
  • 2026

Own product: websites and sales pages for small businesses · Live on its own domain, with paid traffic running

Problem

The home page is a brand piece: it opens with a cinematic sequence several screen-heights tall before it shows the headline. And it is fast — the experience indicators all come out green. But a click arriving from an ad lands on a black screen and only finds the message thousands of scroll pixels later. The mistake never surfaces on the performance dashboard, because the metric measures what got painted, not what got communicated.

Solution

Ad pages became a separate artefact, with rules of their own: no animation library, no navigation menu, the headline text as the first painted element, and one form per campaign so that a contact arrives already attributed. The home page stays cinematic, because for someone arriving from search or a referral it works. Two artefacts, two objectives, measured apart.

Architecture

Static sites published straight from the repository, with clean addresses resolved in host configuration. Each ad page lives in a file of its own and is cloned by changing six things — title, canonical address, headline, image, form name and FAQ — listed in the file’s own header. The measurement layer stamps the click identifier into a hidden form field, which makes the conversion come back attached to the campaign that produced it.

Diagram — MyVibePages: publishes from the repository and returns the conversion tied to the campaign

Stack

The ad page loads no animation library, and that is not byte-shaving: it is what removes, in one move, the opening sequence, the scroll hijacking and an entire class of clipping bug in Apple’s mobile browser. Index blocking, in turn, is done with a meta tag rather than a crawler rule — blocking the crawler would cancel the instruction itself, because a robot kept from reading the page never reads the request sitting inside it.

  • Netlify
  • GitHub

Outcome

The ad page changed what dominates the screen: the largest painted object used to be a fifteen-pixel scroll hint at thirty per cent opacity; now it is the headline itself.

120 msto largest contentful paint (LCP)ago/2026 · before/after measurement
8requests for the entire pageago/2026 · internal telemetry
0cumulative layout shift (CLS)ago/2026 · internal telemetry

Erika RAG

Retrieval over the procedure base — and the rule that the base beats the model, always.

  • In production
  • Corporate system
  • 2026

Procedure base for a service desk operation · Queried by people and by other systems, through the same contract

Problem

The right procedure exists, written down, and still nobody finds it. It sits in a document someone revised eight months ago, under a name that only makes sense to whoever already knew where to look. Worse: when a language model walks into that gap, it fills it with something plausible. An invented procedure is more dangerous than no procedure at all, because it looks like an answer.

Solution

Retrieval over the document base, with a declared and non-negotiable hierarchy: when the user’s words, the model’s inference and the base disagree, **the base wins**. A required field only accepts a value that exists in the base, spelled the way the base spells it — no synonyms, no translation, no variation. And doubt does not become a guess: it becomes a question.

Architecture

The retrieval assets live in cloud object storage, reached through the SDK rather than the mounted filesystem — mounting is convenient and it is a bottleneck. The layer is exposed as a service, which makes it a shared resource: the conversational interface queries it, and a separate triage system queries the same endpoint under the same contract. The inference timeout at the load balancer is 60 seconds, sized for the long retrieval flow — below that, the correct answer was arriving as a gateway error.

Diagram — Erika RAG: retrieval is a service, with two consumers and one contract

Connections

Stack

The decision that holds up the rest is not about infrastructure, it is about precedence: the knowledge base has absolute priority over any inference. That turns hallucination on a required field into a data problem rather than a prompt problem — if the value is not in the base, there is no value to return, and the right path becomes asking. Exposing retrieval as a service, instead of embedding it in each consumer, is what stops two knowledge bases from drifting apart by the third month.

  • LLM
  • Documents
  • REST APIs
  • Google Cloud
  • Java 21

Outcome

It became infrastructure: a second system started querying it in production, and that consumption is what produced the first honest measurements of it — real latency and hit rate, measured from the outside.

7–13 sto answer a queryset/2026 · internal telemetry
5%of conversations yield a usable procedureset/2026 · internal telemetry

Password reset by phone

The service desk’s number one ticket, resolved over the phone at three in the morning, with nobody on the other end.

  • In production
  • Corporate system
  • 2026

Corporate service desk, voice channel · Available outside business hours, with no analyst on duty

Problem

A locked password is the most common ticket and the least interesting of them all. It demands no judgement, it demands availability — and that is precisely where it fails: it happens on Monday morning, at shift change, on a Sunday. While there is no analyst, the person does not work. And the traditional self-service portal is no use to someone who is, by definition, locked out.

Solution

The person calls. Identification is positive and done by voice: the system finds the record from the number that is calling and confirms attributes only the account holder would know. Once identity is confirmed, the reset is delegated — the identity layer performs the change, clears the lockout and marks the password as expired, so the permanent one is chosen by the person themselves at first sign-in. No password is ever spoken aloud by a system.

Architecture

Telephony hands the already-transcribed intent to the orchestrator, which treats the reset like any other action: it picks the tool and calls it. The record lookup starts from the phone number, with character normalisation — a number stored with parentheses, hyphens or spaces has to match the number the carrier delivers. Directory execution does not happen here: it is a call to the identity middleware, which returns only success or failure. The orchestrator never receives a credential, neither the old one nor the new.

Diagram — Password reset: identifies by phone number and delegates execution

Connections

Stack

Reusing the identity middleware, rather than granting yet another system access to the directory, is what keeps a single auditable door for identity actions — and it is the difference between two systems and a platform. Expiring the password at the source is a deliberate choice: it guarantees the temporary value does not outlive the phone call, and it moves the choice of the real password to the person who owns it.

  • Voice
  • LLM
  • REST APIs
  • Directory

Outcome

The operation’s highest-volume ticket stopped depending on shift coverage. No figure is published here because the honest measurement would be a before-and-after of handling time, and that was never instrumented — what exists is the system in production and a complete audit trail in the directory.

Intelligent Qualifier

Classifies the request against a closed catalogue — and the model never writes the category, it only picks an identifier.

  • In production
  • Corporate system
  • 2026-09

First-level support in a service desk operation · A 305-service catalogue, with two production versions compared against each other

Problem

The person opening a ticket does not speak the service catalogue’s language. They say "I lost access to my department’s folder"; the catalogue expects a three-level path, written exactly one way. Translating between the two is first-level work, and it is where tickets land in the wrong queue. Handing that to a language model is tempting and dangerous: it writes a plausible category that does not exist, and the error only shows up in the destination queue.

Solution

The model does not write the category. It picks an identifier from a closed list, and the database resolves the rest. Four steps: a text search brings back about twelve candidates without spending a single token; the model picks one; code checks it; and the final category comes from a catalogue lookup. An identifier outside the list is discarded, even if it exists in the catalogue. Confidence below the floor becomes explicit human triage, not a guess.

Architecture

Before registering anything, the system asks the procedure base whether there is a path the person could follow themselves — and it does not wait for the answer: it already asks the next clarifying question. Not blocking is a measurement, not a style choice, because the query takes seven to thirteen seconds and only one conversation in twenty yields anything usable; waiting would charge everyone the delay in order to serve a few. The procedure that comes back is written for an analyst, so two layers filter it: the model tags each step as user-level or technical, and a blocklist in code discards technical steps even when they arrive tagged as user-level.

Diagram — Classifier: queries the base without waiting, and filters what comes back twice

Connections

Stack

The guard that matters is not in the prompt, it is in the type of the data: what the model returns is an identifier, and what the user reads comes from a database lookup. No improvement in wording can reintroduce an invented category. The same principle governs the self-service filter — what you ask of a model is a request, not a guarantee, which is why code checks again. Temperature is zero by measurement, not by taste: above it, the same sentence changed service between identical runs. And the two live versions run the same image against the same database, differing in a single parameter, so the comparison measures the feature and not two different products.

  • Python
  • LLM
  • PostgreSQL
  • Docker
  • Google Cloud
  • REST APIs

Outcome

Live with dry-run as the default, including in production: opening a ticket is irreversible in the destination system, so leaving dry-run is a deliberate configuration change rather than a button on screen.

~700tokens per classification, against ~22,000 if the whole catalogue were injectedset/2026 · before/after measurement
305services in the catalogue, of which the model sees twelveset/2026 · internal telemetry

Internal tools

Prospecting, proposals and extraction — with the same rule in all of them: the tool only asserts what it verified.

  • In production
  • Internal tool
  • 2026

Tools I built for my own work · Personal and team use, with no external users

Problem

Internal tooling is where discipline usually gets abandoned, because the only user is the person who wrote it. The bill arrives later: a prospecting script that classifies by how a website looks rather than whether one exists, a proposal generator that asserts what nobody checked. The failure is not technical, it is one of honesty — and it travels straight from the tool to a client’s face.

Solution

The rule is the same across all three: every classification produces a piece of evidence, and that evidence is the only thing the generated text may assert. In prospecting, what qualifies a contact is the kind of online presence, not its aesthetics — a short link that ends in a messaging app means no website, not a bad website, and the tool follows the redirects to the final destination before deciding.

Architecture

Prospecting is a Python script that queries the places API, resolves the real online presence and only then asks the model for text, handing it the verified evidence as input — and the model at that step is the fast one, because every run weighs many businesses. The proposal generator is a single-page application with the model call isolated in a serverless function, which validates the session before spending the writing model — the key never reaches the browser, which is the difference between an internal tool and a leaked credential. The third is a website content extractor, input for the other two; but neither of them calls it: it runs outside and its output goes in by hand.

Diagram — Internal tools: three utilities, one rule — only assert what was verified

Stack

Keeping the API key in the serverless function rather than the front end is the decision that pays for itself the most: an internal tool becomes public the day someone publishes the repository. And separating verification from writing — check first, then ask for the text — is what makes it possible to swap models without the honesty of the result depending on which model was chosen.

  • Python
  • Claude
  • LLM
  • REST APIs
  • Vercel

Outcome

These are tools for my own use, with no external users and no figure worth publishing. They are here for one reason: they show that the same rule governing the corporate systems — the machine does not assert what it has not verified — was applied where nobody was watching, too.