{
  "id": 9687194,
  "title": "Your Agent's Free-Text Output Is an API You Never Designed",
  "url": "https://urgent.news/2026/09/25/your-agents-free-text-output-is-an-api-you-never-designed",
  "topic": "ai",
  "section": "AI",
  "published": "2026-09-25T02:40:58.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/ruixuan_jiang_663eb75f3fa/your-agents-free-text-output-is-an-api-you-never-designed-3mb9"
  },
  "original_language": "en",
  "account": "Most agent demos fail at the same place, not because of the model but at the boundary where the model's output transitions to your program. Strings lack a schema, leading to code like this:\n\nconst reply = await llm.complete(prompt);\n\nIf the model writes \"I would not approve this yet,\" your substring check might match \"approve,\" resulting in unintended code execution.\n\nAn API emerges whenever you attempt to comprehend meaning from generated text. You don't consciously define this interface, but it exists nonetheless. This interface lacks versioning, validation, and logging capabilities. Prompt engineering can reduce failure rates but doesn't eliminate the parsing issue. Instead, ask the model for a decision, not a paragraph.\n\nTypically, an agent step requires two different outputs: a description for humans and a decision for the program. The decision should come from a predefined set comprehended by your code. For example:\n\ntype ReviewDecision = {\nstatus: 'pass' | 'review' | 'fail';\nconfidence: 'low' | 'medium' | 'high';\nfindings: Array<{ file: string; note: string; severity: 'info' | 'warn' | 'block' }>;\n};\n\nNow, failure modes become distinct: model-produced errors, contract violations, or implementation bugs. Validate before acting. Implementing a typed boundary ensures errors are recoverable before merging, paying or deploying.\n\nInclude evidence with the decision to make it trustworthy. Provide inputs the model saw, the allowed output space, the chosen value, and supporting evidence. This approach enables replayable records, helping identify issues when bad decisions are shipped. While typing the output doesn't guarantee correctness or replace other measures, it clarifies the control signal, making the system easier to reason about.",
  "summary": "Most agent demos fail in the same place, and it is not the model. It is the boundary where the model's output leaves the model and enters your program. Up to that point it is a string. Strings do not have a schema. So you end up with code like this: const reply = await llm . complete ( prompt ); // please work if ( reply . toLowerCase (). includes ( \" approve \" )) { await merge (); } else { await…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}