<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Kortix]]></title><description><![CDATA[Kortix is an open-source CompanyOS — your agents, skills, company memory, and connectors in one git repo you own. Any model, your keys, self-hosted or managed cloud.]]></description><link>https://kortix.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6ae2f6edc29676b79c30f242/5aaa4665-fb3d-4810-bc16-2f44e5b5f99e.png</url><title>Kortix</title><link>https://kortix.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 05 Nov 2026 13:42:14 GMT</lastBuildDate><atom:link href="https://kortix.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Open-source agent tool access starts at the credential boundary]]></title><description><![CDATA[Handing an agent a Stripe key is a decision about where that key lives. The model's instructions are the least reliable part of the arrangement, since…]]></description><link>https://kortix.hashnode.dev/open-source-agent-tool-access-starts-at-the-credential-boundary</link><guid isPermaLink="true">https://kortix.hashnode.dev/open-source-agent-tool-access-starts-at-the-credential-boundary</guid><category><![CDATA[AI]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[agents]]></category><category><![CDATA[Security]]></category><category><![CDATA[technology]]></category><dc:creator><![CDATA[emily]]></dc:creator><pubDate>Sat, 31 Oct 2026 20:57:26 GMT</pubDate><content:encoded><![CDATA[<p>Handing an agent a Stripe key is a decision about where that key lives. The model's instructions are the least reliable part of the arrangement, since everything in a context window competes with them. Kortix is the open-source CompanyOS, and its position is simple: connector credentials stay outside the sandbox, and the rules that govern each call sit in the project repository, where a reviewer can read them.</p>
<h2>The blast radius belongs to the tools</h2>
<p>A chat window that drafts a refund email risks an embarrassing sentence. An agent that can call Stripe risks money. The reach of a compromised session is the reach of its connected tools. Agent security keeps turning into tool security. <a href="https://auth0.com/blog/api-key-security-for-ai-agents">Auth0's API Keys and AI Agents: Four Common Risks</a> names four: leaked keys, over-privileged tokens, prompt injection, and no audit trail.</p>
<p>That framing makes the useful question concrete. Which credential does this call use, who can trigger it, and what happens before a write leaves the machine? A careful prompt answers none of those. A prompt is a suggestion the model weighs against everything else in its context, including text that arrived from a document, a web page or an inbox. Whatever decides whether the call runs has to sit outside the model.</p>
<h2>Where the credential sits decides the failure mode</h2>
<p>Two credentials look alike in a dashboard and behave nothing alike in a session. A connector credential is brokered server-side. The agent asks for an action, Kortix resolves the secret outside the sandbox, calls the provider, and records what happened. Connector credentials never enter the machine. A secret you grant to an agent is a different object. Environment is the default exposure: the sandbox receives the real value, and any command the agent runs can read it. Egress-enforced is experimental. There the sandbox holds a handle worth nothing on its own, and Kortix substitutes the real value outside the sandbox, only on requests to the HTTPS hosts you list (<a href="https://kortix.com/docs/project/secrets">secrets</a>). Connector brokering and a granted secret answer different needs, and the difference should decide how much reach an agent gets.</p>
<p>The network does not sort this out for you. Nothing enforces network egress on a session: the sandbox can reach the internet, and no rule polices where a request goes. The <code>network_egress</code> block in a manifest is a declaration only. Validation warns that egress is not enforced (<a href="https://kortix.com/docs/project/manifest">manifest reference</a>). The credential is the boundary that holds, and where it lives deserves more design attention than any line in the system prompt.</p>
<h2>The grant is a file you can read</h2>
<p>A support project's reach fits in one short <code>kortix.yaml</code>. This manifest declares one connector, sets two rules on it, and grants that connector to one agent.</p>
<pre><code># kortix.yaml, schema version 2
kortix_version: 2
default_agent: support

connectors:
  - slug: stripe
    name: Stripe
    provider: openapi
    spec: https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json
    policies:
      - match: "get_*"
        action: always_run
      - match: "*"
        action: require_approval

agents:
  support:
    connectors: [stripe]
    secrets: none
    kortix_permissions: none
  release-bot:
    connectors: none
    secrets: none
    kortix_permissions: [project.gitops.push, project.review.submit]
</code></pre>
<p>Read it as three answers. <code>default_agent</code> names the agent a session starts as. The connector is declared once for the project, and its rules are relative to it. Every <code>get_*</code> action runs, and every other action, writes included, waits for a person. The <code>agents</code> block holds governance only. <code>support</code> receives Stripe and no secret at all, while <code>release-bot</code> receives no connector and can push a branch and open a change request. Connecting an app to a project and granting it to an agent are separate acts. The file makes that visible in two lines.</p>
<p>The manifest is checked before it runs. <code>kortix validate</code> reads it against the schema. <code>kortix ship</code> runs the same check before it pushes (<a href="https://kortix.com/docs/cli">CLI reference</a>). An agent that has no grant for a connector has no way to call it, whatever its instructions say.</p>
<h2>Allow, Ask and Block run at call time</h2>
<p>The three actions on a connector are Allow, Ask and Block. Kortix evaluates them when a call is made. An Ask holds the call: the agent's turn pauses and resumes when a person decides. That approval covers one exact request, with the same connector, action, arguments and account, so a changed argument needs a new decision. The approval shows the redacted arguments the provider will receive. The decision goes back into the session (<a href="https://kortix.com/docs/connect/connectors">connectors</a>). Every action is recorded. Reading, exporting and streaming the audit log depend on the plan.</p>
<p>Approval gates you set. Off until you set them. <code>policy.default_mode</code> falls back to <code>allow_all</code>, which runs every action no rule matched, reads and writes alike (<a href="https://kortix.com/docs/connect/connectors">connectors</a>). It is the first thing to change on a project that can touch money. Setting <code>default_mode: risk</code> holds writes and destructive actions while reads run. A connector rule or a project-wide rule then narrows one action at a time. Rules can test arguments too, so a message to one domain can run while every other recipient waits.</p>
<h2>The .env shortcut puts the key back in the sandbox</h2>
<p>The shortcut that undoes all of this is familiar. Put <code>STRIPE_SECRET_KEY</code> and <code>GITHUB_TOKEN</code> in a <code>.env</code> file, ship the file with the agent, and let the instructions ask for care. It works until the first log line, the first file read, or the first subprocess that prints its environment into a log. The key is also broader than the task, because it carries whatever rights the person who minted it had. The provider's logs then show a shared key, with no record of the agent, session or approval behind a call. Rotating it breaks every workflow that uses it, which is why nobody rotates it.</p>
<p>The alternative costs one line per agent in the manifest. <code>secrets</code> is a grant, and an agent that does not list a name does not receive it. That is a small amount of typing for a boundary you can point at in review.</p>
<h2>Durable change arrives as a diff</h2>
<p>Policies drift. Someone widens a rule during an incident, the incident ends, and the rule stays. The policy is a file in the repository, so an agent that changes it works on a session branch and proposes the change. Session work reaches <code>main</code> through a change request, and merge is default-deny for agents. A reviewer sees the exact rule that will govern tomorrow's calls beside the task that motivated it, and <code>git revert</code> is the undo.</p>
<p>A person who manages the project can change connector policy without a change request. Changing a connector rule in the dashboard applies at once (<a href="https://kortix.com/docs/connect/connectors">connectors</a>). Agent grants follow the same shortcut on a <code>kortix_version: 2</code> manifest: the dashboard and the CLI commit <code>kortix.yaml</code> on the default branch, and on v3 a grant change goes through a change request (<a href="https://kortix.com/docs/project/agents">agents</a>). That is the same boundary seen from the other side: whoever can change policy or grants can widen what an agent may do, which is why the ability belongs with the people who manage the project.</p>
<p>The same manifest that defines the boundary travels with the project. Run it on Kortix Cloud, in your VPC, or on your own on-prem network, and the rules you reviewed are the rules that execute. A company can read its tool access in a repository, review an agent's change as a diff, and point at the credential boundary in a security review. An operator can defend that arrangement to a security questionnaire, and the reviewer can check it without opening a prompt.</p>
<p><strong>Keep the credential out of the agent's reach.</strong> Start with one connector, set Ask on the write, and read the grant before it ships. Free to start, free to self-host. <a href="https://kortix.com">kortix.com</a></p>
<p><em>Originally published at <a href="https://kortix.com/blog/secure-ai-agent-tool-access">https://kortix.com/blog/secure-ai-agent-tool-access</a>.</em></p>
]]></content:encoded></item><item><title><![CDATA[Claude Desktop for Linux needs KVM on every laptop. An open-source CompanyOS runs the agent on a machine you own]]></title><description><![CDATA[Cowork on Linux runs in a QEMU/KVM virtual machine the app hosts on your own machine, so the hypervisor and the record matter more than the distro. You can…]]></description><link>https://kortix.hashnode.dev/claude-desktop-for-linux-needs-kvm-on-every-laptop-an-open-source-companyos-runs-the-agent-on-a-mach</link><guid isPermaLink="true">https://kortix.hashnode.dev/claude-desktop-for-linux-needs-kvm-on-every-laptop-an-open-source-companyos-runs-the-agent-on-a-mach</guid><category><![CDATA[AI]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[agents]]></category><category><![CDATA[automation]]></category><category><![CDATA[technology]]></category><dc:creator><![CDATA[emily]]></dc:creator><pubDate>Fri, 30 Oct 2026 18:16:00 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p>Cowork on Linux runs in a QEMU/KVM virtual machine the app hosts on your own machine, so the hypervisor and the record matter more than the distro.</p>
</blockquote>
<p>You can install Claude Desktop on Linux today. Anthropic ships a beta package from its own apt repository for Ubuntu 22.04 or later and Debian 12 or later, on x64 and arm64 (<a href="https://code.claude.com/docs/en/desktop-linux">requirements</a>), and Fedora and Arch have no official package. The part worth settling before a rollout is quieter: on Linux the agentic half of the app runs inside a virtual machine the app hosts, and what the agent did stays with the person who ran it.</p>
<h2>What the beta installs</h2>
<p>The Debian build ships the full app. It launches as <code>claude-desktop</code> and signs in with a claude.ai subscription or your organization's SSO. Chat runs on every plan. Claude Code runs inside the desktop app, and Cowork is included on paid plans, so there is a Claude Code desktop app for Ubuntu from the same repository. API keys are the exception: those stay with the CLI.</p>
<p>Anthropic lists the gaps itself. Linux support is beta for Ubuntu and Debian, and "Support for additional distributions is coming in the future" (<a href="https://claude.com/download">download</a>). Computer Use is "not yet available on Linux", and dictation "is also not available in this release". Quick Entry's hotkey works on X11; on native Wayland it needs the desktop's GlobalShortcuts portal.</p>
<p>The app's update path matters at fleet scale. "The desktop app doesn't update itself on Linux". Updates arrive with the system's package updates, so the app inherits whatever patch policy apt already has.</p>
<h2>Cowork is a virtual machine the app hosts</h2>
<p>Cowork is the part of the app that takes a longer task and carries it out. On Linux it "runs those tasks in a virtual machine that the desktop app hosts with QEMU and KVM", so the machine the agent works on is the one the app is installed on.</p>
<p>The KVM requirements follow from the design. Virtualization has to be on in firmware. <code>qemu-system-x86</code>, <code>ovmf</code> and <code>virtiofsd</code> have to be installed. The app opens <code>/dev/kvm</code> and <code>/dev/vhost-vsock</code>. Only kvm group members can open the second one, so the account running the app needs <code>sudo usermod -aG kvm $USER</code> and a fresh login. The checks run once at launch, so a fresh package install needs a restart.</p>
<p>A sandbox that keeps an agent off the rest of a laptop is a fair design. The question is who owns the boundary. On Linux the boundary belongs to whoever provisions the machine: every install needs its own hypervisor, its own device group, and a kernel built with that support compiled in.</p>
<h2>The published floor and the hosts that clear it</h2>
<p>Take the requirement list literally and check a host. The transcript is abridged to the lines the check reads.</p>
<pre><code class="language-text">$ grep '^PRETTY_NAME' /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
$ dpkg --print-architecture
amd64
$ ls -l /dev/kvm /dev/vhost-vsock
ls: cannot access '/dev/kvm': No such file or directory
ls: cannot access '/dev/vhost-vsock': No such file or directory
</code></pre>
<p>Debian 12 on amd64 is inside Anthropic's supported matrix, and the two device nodes the app opens, /dev/kvm and /dev/vhost-vsock, are both missing, so Cowork cannot start its virtual machine there. Anthropic's docs describe one class of host where no fix exists: when /dev/vhost-vsock is missing and the running kernel has no module directory, the app reports that the kernel "doesn't include the virtualization support Cowork needs and that it can't be added manually", a combination the docs call common "on ChromeOS and in container-based Linux environments."</p>
<p>Anyone can run those three checks, the distribution, the architecture and the two device nodes, on a fleet in a minute. A host that passes the first two and fails the third is the one to plan around.</p>
<p>A workstation with virtualization switched on in firmware passes cleanly. There the cost is one command and a re-login, which is a small price for a beta that otherwise works. The cost turns structural where the firmware setting is not yours to change: ChromeOS devices, container images, virtual desktops without nested virtualization, managed laptops with locked boot settings. No distro upgrade fixes those. <code>usermod</code> has nothing to add the account to.</p>
<h2>Somebody already shipped a fallback</h2>
<p>The clearest sign the requirement blocks people is that someone built an exit. aaddrick/claude-desktop-debian ships a Cowork bubblewrap backend, "Opt-in via <code>COWORK_VM_BACKEND=bwrap</code> for hosts without KVM/vhost-vsock", gated on the flag so an unflagged launch runs Anthropic's path unchanged (<a href="https://raw.githubusercontent.com/aaddrick/claude-desktop-debian/main/README.md">README</a>). The project exists because Anthropic ships one packaging target. It repackages that official <code>.deb</code> into .rpm, AppImage and Nix flake builds, and names them <code>claude-desktop-unofficial</code> so they install beside the original.</p>
<p>On Fedora a community script skips the packaging work. It verifies Anthropic's signing key, the signed repository index and the package checksums, then installs into <code>~/.local</code>, and it was tested on Fedora 44 Workstation x86_64 (<a href="https://discussion.fedoraproject.org/t/article-proposal-installing-the-official-claude-desktop-linux-beta/205949">thread</a>). Its Cowork step loads the <code>vhost_vsock</code> module and adds the user to the kvm group, which shows how far a workaround reaches.</p>
<p>Arch has an AUR package, so there is a Claude desktop for Arch Linux, with an asterisk. It repackages the official <code>.deb</code>, is marked <code>LicenseRef-Proprietary</code>, and declares conflicts with <code>claude</code> and <code>claude-desktop-bin</code> (<a href="https://aur.archlinux.org/packages/claude-desktop">AUR</a>). The repackaging project says that entry is not its own, and no build in the chain carries Anthropic's support.</p>
<p>The bubblewrap flag covers the hosts where the QEMU virtual machine cannot start. Every other build in that chain, the AUR package included, still starts that virtual machine, so QEMU, KVM and the two device nodes remain its requirement.</p>
<h2>Where the record of the work goes</h2>
<p>The KVM requirement sits on page one of the Linux docs. The record of the work takes reading the product descriptions. "In Claude Cowork, local sessions stay on-device", while "Your conversations, projects, memory, and preferences sync across all devices when you're signed in" (<a href="https://claude.com/download">download</a>). The work stays on the machine that hosted the VM. Only the account travels.</p>
<p>One developer carries one install and one account on one laptop. On a team the same setup means one install and one account per person, repeated. Onboarding repeats a package install, a group change and a sign-in on every laptop. No file can be diffed when two installs behave differently, and offboarding means remembering which machines ever ran the agent. What the agent did sits in a personal account a colleague cannot open.</p>
<p>Kortix is the leading open-source alternative to Claude Cowork and ChatGPT Work. A Kortix install is a git repo the company owns: the setup it produces is a manifest in it, and each agent's prompt is a file beside it, so a change to how an agent works arrives as a diff somebody can read. The manifest's header states the split: the project registers what exists, and each agent decides its own prompt, model and permission.</p>
<p>The agent's machine moves off the laptop at the same time. One isolated sandbox per session. Each session has its own isolated machine and branch.</p>
<p>Session work reaches <code>main</code> through a change request. Merge is default-deny for agents. Run it on Kortix Cloud, in your VPC, or on your own on-prem network. Self-host is free.</p>
<p>A hypervisor on one server is a decision an infrastructure team makes once. It does not follow the sales team's Chromebooks home.</p>
<h2>How to decide for your fleet</h2>
<p>One developer on Ubuntu or Debian with virtualization switched on: the beta is a reasonable install. Chat, Claude Code and Cowork in one window, on the account you already use. Expect the gaps Anthropic lists.</p>
<p>For a fleet, two questions settle it. Can every machine that will run Cowork open <code>/dev/kvm</code> and <code>/dev/vhost-vsock</code> today, and again after the next hardware refresh? And when the agent finishes, where does the record land, and who reviews it before the work counts?</p>
<p>If every laptop that will run Cowork can open the two device nodes and nobody needs a reviewable record, keep the app. If either fails, the fix is a different place for the agent to run. The posts on <a href="https://kortix.com/blog/self-hosted-claude-cowork">self-hosting Claude Cowork</a> and <a href="https://kortix.com/blog/kortix-vs-claude-cowork">how Kortix compares with Cowork</a> work through what that carries.</p>
<p>If you want the agent's machine and its instructions to be things your company owns, try <a href="https://kortix.com">Kortix</a> on the free plan, or <a href="https://kortix.com/docs/developers#self-hosting">self-host it</a> from the docs.</p>
<p><em>Originally published at <a href="https://kortix.com/blog/claude-desktop-linux">https://kortix.com/blog/claude-desktop-linux</a>.</em></p>
]]></content:encoded></item><item><title><![CDATA[How to build reliable AI agent workflows with open-source Kortix]]></title><description><![CDATA[Map AI agent workflow failure modes to concrete controls, with a reference implementation on open-source Kortix. Agent workflows fail in ways a generic…]]></description><link>https://kortix.hashnode.dev/how-to-build-reliable-ai-agent-workflows-with-open-source-kortix</link><guid isPermaLink="true">https://kortix.hashnode.dev/how-to-build-reliable-ai-agent-workflows-with-open-source-kortix</guid><category><![CDATA[AI]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[Devops]]></category><category><![CDATA[open source]]></category><dc:creator><![CDATA[emily]]></dc:creator><pubDate>Thu, 29 Oct 2026 14:20:31 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p>Map AI agent workflow failure modes to concrete controls, with a reference implementation on open-source Kortix.</p>
</blockquote>
<p>Agent workflows fail in ways a generic retry does not fix. A tool reports success with an error payload inside. A schema drifts, a loop never exits, and the fix each time is engineering around the model: name the failure mode, attach a control, instrument the signal that proves it holds. Kortix is the open-source platform that supplies those primitives, from a sandbox per session to a review gate on every change.</p>
<h2>Why agent workflows fail in production</h2>
<p>Agent workflow failures cluster into a small set of recurring modes. Each one needs its own control and its own signal, and a generic "add retries" fix covers one row while the rest stay exposed.</p>
<table>
<thead>
<tr>
<th>Failure mode</th>
<th>What it looks like</th>
<th>Control</th>
<th>Signal</th>
</tr>
</thead>
<tbody><tr>
<td>Silent tool failure</td>
<td>A tool returns success with an error payload, an empty result or a stale value</td>
<td>Validate the result content, not the transport status</td>
<td>Tool-error and empty-result rate</td>
</tr>
<tr>
<td>Schema drift</td>
<td>An upstream API renames or retypes a field while the agent parses the old shape</td>
<td>Validate typed input and output at every step boundary</td>
<td>Schema-validation failures per step</td>
</tr>
<tr>
<td>Non-determinism</td>
<td>The same input produces different plans or outputs across runs</td>
<td>Pin the model and version, and run a fixed eval set</td>
<td>Eval pass-rate variance</td>
</tr>
<tr>
<td>Context rot</td>
<td>The model misses a fact as the context fills with distractors</td>
<td>Retrieve only relevant context, compress it, restate the task</td>
<td>Task-success rate against context size</td>
</tr>
<tr>
<td>Compounding errors</td>
<td>One wrong step becomes the input to the next</td>
<td>Programmatic gates between steps and a bounded verifier pass</td>
<td>Gate-failure and rework-loop rate</td>
</tr>
<tr>
<td>Runaway loops</td>
<td>The agent iterates because no exit condition ever evaluates true</td>
<td>Cap iterations and set explicit stopping conditions and budgets</td>
<td>Timeouts and cost per task</td>
</tr>
<tr>
<td>Unguarded side effects</td>
<td>The agent sends, deletes or charges without review</td>
<td>Human approval before irreversible actions, and least-privilege credentials</td>
<td>Unapproved actions, which should be zero</td>
</tr>
<tr>
<td>Duplicate side effects</td>
<td>A retried call creates a second resource</td>
<td>Idempotency keys, timeouts, capped backoff with jitter, a circuit breaker</td>
<td>Duplicate-action and circuit-open counts</td>
</tr>
</tbody></table>
<p>Context rot shows why a control has to match its mode. Chroma's evaluation found model performance degrading as input length grows, and topically related distractors push it down further (<a href="https://research.trychroma.com/context-rot">Chroma</a>). One structural choice comes before any of these controls: how much of the flow the model is allowed to decide.</p>
<h2>Choose the simplest structure that fits</h2>
<p>Anthropic separates a workflow from an agent (<a href="https://www.anthropic.com/engineering/building-effective-agents">Anthropic</a>). A workflow orchestrates models and tools through predefined code paths, while an agent lets the model direct its own process and its own tool use. Both are agentic systems. They carry different failure profiles: the workflow is predictable and rigid, the agent flexible and exposed to compounding errors.</p>
<p>Google Cloud reaches the same conclusion from the design side. Start with a single agent, so you can refine the core logic, the prompt and the tool definitions before adding more (<a href="https://docs.cloud.google.com/architecture/choose-design-pattern-agentic-ai-system">Google Cloud</a>). Performance drops as that one agent takes on more tools and harder tasks, and you see it as latency, wrong tool selection or unfinished work. Anthropic's advice is the same: find the simplest solution possible, and add complexity only when it earns its place.</p>
<h2>Bound the loop and make retries safe</h2>
<p>The loop is where an agent's flexibility turns expensive. Google Cloud describes a loop pattern that repeats subagents until a termination condition is met. It warns that the "primary trade-off is the risk of an infinite loop" when that condition is not correctly defined (<a href="https://docs.cloud.google.com/architecture/choose-design-pattern-agentic-ai-system">Google Cloud</a>). So set an exit condition the workflow can actually evaluate, plus a cap on iterations and a budget for time and tokens. Anthropic lists stopping conditions such as a maximum number of iterations as part of the design (<a href="https://www.anthropic.com/engineering/building-effective-agents">Anthropic</a>).</p>
<p>Retries help with transient faults. They work only when the operation is idempotent. AWS's guidance: the effect of a retried call should happen once, even when the call is made many times (<a href="https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/">AWS</a>). Timing matters too. Capped exponential backoff with jitter spreads retries out. Clients stop retrying in synchronized bursts (<a href="https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/">AWS</a>). A timeout bounds each attempt. A circuit breaker stops calling a service once failures cross a threshold, which gives it room to recover (<a href="https://learn.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker">Azure</a>). For a long run, durable execution takes the workflow to completion and, after a crash, resumes at the point where it stopped (<a href="https://docs.temporal.io/evaluate/understanding-temporal">Temporal</a>).</p>
<h2>Validate every boundary and gate every side effect</h2>
<p>Every boundary between steps is a place where a wrong shape gets in. Define the expected input and output of each step. Validate both against a schema before the next step consumes the result. JSON Schema is a common way to express that shape, and a mismatch fails fast instead of flowing downstream (<a href="https://json-schema.org/understanding-json-schema">JSON Schema</a>).</p>
<p>Anthropic warns that agents carry "the potential for compounding errors", so a wrong step should not quietly become the input to the next (<a href="https://www.anthropic.com/engineering/building-effective-agents">Anthropic</a>). Put programmatic checks between steps. Add a bounded verifier pass with explicit pass criteria. Google Cloud's review-and-critique pattern gives a critic predefined criteria to evaluate output against, and Anthropic's evaluator-optimizer runs a generator and a critic in a loop (<a href="https://docs.cloud.google.com/architecture/choose-design-pattern-agentic-ai-system">Google Cloud</a>, <a href="https://www.anthropic.com/engineering/building-effective-agents">Anthropic</a>).</p>
<p>Some actions should never run unattended. Google Cloud asks whether a task involves high-stakes decisions, safety-critical operations or subjective approvals that need human judgment (<a href="https://docs.cloud.google.com/architecture/choose-design-pattern-agentic-ai-system">Google Cloud</a>). Anthropic notes that agents can pause for human feedback at checkpoints or blockers (<a href="https://www.anthropic.com/engineering/building-effective-agents">Anthropic</a>). Gate irreversible actions behind approval. Give the agent only the credentials it needs.</p>
<h2>Track the signals that prove a control holds</h2>
<p>Observability has to cover the deterministic parts of a workflow and the probabilistic ones. The OpenTelemetry GenAI semantic conventions define spans, metrics and events for GenAI clients and MCP, which gives traces a shared vocabulary instead of a one-off log format (<a href="https://github.com/open-telemetry/semantic-conventions-genai">OpenTelemetry</a>).</p>
<p>Read those signals per step. Emit one span for each step. It carries the inputs, outputs, latency and errors. Then track a short list per tool: the tool-error and empty-result rate, schema-validation failures, task-success and rework-loop rates, cost per task. Hold a fixed eval set of representative tasks. Run it before any change to a prompt, a tool or a model. Anthropic recommends comprehensive evaluation and sandboxed testing with guardrails (<a href="https://www.anthropic.com/engineering/building-effective-agents">Anthropic</a>).</p>
<h2>Reliable workflows on open-source Kortix</h2>
<p>Kortix is the open-source AI Operating System: agents, shared skills, company memory and connectors live in one git repo you own. A session runs an agent in an isolated sandbox. Each session works on its own branch, and the agent opens a change request a human reviews and merges (<a href="https://kortix.com/docs">Kortix docs</a>). Per-agent grants scope connectors, secrets and skills. Connector credentials are brokered server-side, so raw keys never enter the machine, and a full audit trail records what ran (<a href="https://github.com/kortix-ai/suna">Kortix on GitHub</a>). Kortix is open source. Self-host it, bring any model provider with your own keys, and start free on one project.</p>
<pre><code class="language-yaml"># kortix.yaml: governance only; the agent's behavior lives in agents/workflow-runner.md
kortix_version: 2
default_agent: workflow-runner
agents:
  workflow-runner:
    connectors: [github]
    secrets: []
    skills: [reliability-checks]
triggers:
  - slug: nightly-run
    type: cron
    cron: "0 0 3 * * *"
    agent: workflow-runner
    prompt: |
      Validate every tool result against its schema, stop after five
      iterations, and open a change request instead of writing to main.
</code></pre>
<p>The platform supplies the controls that are expensive to build twice: isolation per session, a review gate before work lands, scoped credentials and an audit trail. Run it on Kortix Cloud, in your VPC, or on your own on-prem network (<a href="https://github.com/kortix-ai/suna">Kortix on GitHub</a>). Self-host is free. You still define the schemas, the exit conditions, the budgets and the eval set for each workflow.</p>
<p>If tool access is the part you are hardening, <a href="https://kortix.com/blog/secure-ai-agent-tool-access">how to give AI agents tool access safely</a> covers scoped connectors and approval policies. <a href="https://kortix.com/blog/open-source-ai-agent-platform">Open-source AI agent platforms</a> compares the options on licence, deployment and model choice. <a href="https://kortix.com/blog/getting-started-with-kortix">Getting started with Kortix</a> walks through the first session.</p>
<p>Start with one workflow. Name its failure modes, attach a control to each, and measure the signal that proves the control holds. <a href="https://kortix.com">Get started with open-source Kortix</a>, or <a href="https://kortix.com/docs">read the docs</a> to run the reference shape yourself.</p>
<p><em>Originally published at <a href="https://kortix.com/blog/how-to-build-reliable-ai-agent-workflows">https://kortix.com/blog/how-to-build-reliable-ai-agent-workflows</a>.</em></p>
]]></content:encoded></item></channel></rss>