[{"data":1,"prerenderedAt":778},["ShallowReactive",2],{"blog-agent-tool-design-descriptions-errors-en":3},{"slug":4,"published":5,"minutes":6,"category":7,"tags":8,"keywords":14,"about":25,"sources":35,"cover":57,"og":58,"expertise":59,"locales":60,"lang":61,"title":64,"description":65,"coverAlt":66,"metaTitle":67,"takeaways":68,"faq":74,"toc":90,"blocks":124,"others":518},"agent-tool-design-descriptions-errors","2026-10-17",11,"agents",[9,10,11,12,13],"AI agents","Tool use","Function calling","MCP","Agent design",[15,16,17,18,19,20,21,22,23,24],"agent tool design","writing tool descriptions for llm","function calling best practices","tool use error handling","mcp tool design","tool calling is_error","how many tools should an agent have","tool search defer_loading","agent computer interface","llm tool schema design",[26,29,32],{"name":27,"url":28},"Intelligent agent","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FIntelligent_agent",{"name":30,"url":31},"Model Context Protocol","https:\u002F\u002Fmodelcontextprotocol.io\u002F",{"name":33,"url":34},"Poka-yoke","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPoka-yoke",[36,39,42,45,48,51,54],{"title":37,"url":38},"Anthropic Engineering: Writing effective tools for agents, with agents (Sep 2025)","https:\u002F\u002Fwww.anthropic.com\u002Fengineering\u002Fwriting-tools-for-agents",{"title":40,"url":41},"Anthropic Engineering: Building effective agents (Dec 2024)","https:\u002F\u002Fwww.anthropic.com\u002Fengineering\u002Fbuilding-effective-agents",{"title":43,"url":44},"Claude Platform Docs: Define tools","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fagents-and-tools\u002Ftool-use\u002Fdefine-tools",{"title":46,"url":47},"Claude Platform Docs: Handle tool calls","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fagents-and-tools\u002Ftool-use\u002Fhandle-tool-calls",{"title":49,"url":50},"Claude Platform Docs: Tool search tool","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fagents-and-tools\u002Ftool-use\u002Ftool-search-tool",{"title":52,"url":53},"Model Context Protocol specification 2025-11-25: Tools","https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2025-11-25\u002Fserver\u002Ftools",{"title":55,"url":56},"OpenAI API Docs: Function calling","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Ffunction-calling","\u002Fimages\u002Fblog\u002Fagent-tool-design-descriptions-errors\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fagent-tool-design-descriptions-errors\u002Fog.jpg","ai-engineer",[61,62,63],"en","de","hu","Designing tools for AI agents: names, descriptions, schemas and error messages","How to design agent tools that get picked and called correctly: task-shaped tools, descriptions, schemas, compact responses and errors a model can act on.","Three rectangular slots in a base, with a block of matching width lined up over the middle slot and two wrong-width blocks beside it.","Designing tools for AI agents · Balázs Csorba",[69,70,71,72,73],"Tool definitions are prompt text. Anthropic calls detailed descriptions by far the most important factor in tool performance.","Design tools around tasks, not endpoints: one schedule_event beats list_users, list_events and create_event.","Make mistakes hard with the schema: enums, required ids, absolute paths, strict mode, and no arguments the code already knows.","Return high-signal results with names instead of opaque ids, paginate by default, and offer a concise response format.","Errors are instructions. Return them as tool results with is_error or isError, saying what went wrong and what to try next.",[75,78,81,84,87],{"q":76,"a":77},"How long should a tool description be?","Anthropic recommends at least three to four sentences per tool, more for complex tools, covering what the tool does, when to use it and when not to, what each parameter means, and its limitations. A one-line description such as \"Gets the stock price for a ticker\" leaves the model guessing.",{"q":79,"a":80},"How many tools can an agent handle?","OpenAI suggests aiming for fewer than 20 functions at the start of a turn. Anthropic says Claude's tool selection degrades beyond 30 to 50 tools and recommends tool search once you have 10 or more tools or definitions above 10,000 tokens. Above that, load tools on demand instead of all up front.",{"q":82,"a":83},"Should tool errors be raised as exceptions or returned to the model?","Return execution errors to the model as a tool result with is_error true on the Claude API or isError true in MCP, so it can correct itself. The MCP specification reserves JSON-RPC protocol errors for unknown tools and malformed requests, which models are less likely to recover from.",{"q":85,"a":86},"Is it better to have one tool per API endpoint?","Usually not. Anthropic advises against wrapping every endpoint and suggests consolidating multi-step work into one tool, and OpenAI says to combine functions that are always called in sequence. Fewer, more capable tools reduce selection mistakes and save context.",{"q":88,"a":89},"Can I trust MCP tool annotations like read-only hints?","Not by default. The MCP specification says clients must treat tool annotations as untrusted unless they come from trusted servers. Use them for display and as hints, but enforce permissions, confirmations and rate limits in your own code.",[91,94,97,100,103,106,109,112,115,118,121],{"id":92,"title":93},"tools-are-prompts","Tool definitions are prompts",{"id":95,"title":96},"choose-tools","Build tools around tasks, not endpoints",{"id":98,"title":99},"naming","Names and namespaces",{"id":101,"title":102},"descriptions","Writing descriptions the model can act on",{"id":104,"title":105},"schemas","Schemas that make mistakes hard",{"id":107,"title":108},"responses","Responses: high signal, few tokens",{"id":110,"title":111},"errors","Error messages are instructions",{"id":113,"title":114},"many-tools","When the tool list grows",{"id":116,"title":117},"safety","Tools are an attack surface",{"id":119,"title":120},"evaluate-tools","Evaluate tools, then iterate",{"id":122,"title":123},"sources","Sources",[125,134,137,140,147,150,151,170,238,251,252,277,298,299,302,304,311,312,315,359,367,368,375,384,392,393,404,406,413,420,421,428,450,457,458,464,476,477,480,492,493],{"type":126,"content":127},"paragraph",[128,129,133],"When an agent misbehaves, the first instinct is to rewrite the system prompt. Often the problem sits one layer lower, in the tools: a name that could mean two things, a description that never says when not to use it, a parameter called ",{"tag":130,"children":131},"code",[132],"user"," that accepts anything, a search that returns 40,000 tokens of JSON, or an error that says only \"failed\". The model reads all of that on every turn, and it can only be as good as what it reads.",{"type":126,"content":135},[136],"This guide collects what Anthropic, OpenAI and the MCP specification say about tool design and turns it into concrete rules: which tools to build, how to name and describe them, how to shape schemas so mistakes are hard, what to return, how to report errors so the model recovers, and what to do when the tool list grows past a few dozen. The examples come from the kind of B2B shop and back-office agents I build.",{"type":138,"level":139,"id":92,"text":93},"heading",2,{"type":126,"content":141},[142,143,146],"On the Claude API, the ",{"tag":130,"children":144},[145],"tools"," parameter is turned into a system prompt: the API builds a special prompt from your tool definitions, tool configuration and your own system prompt. Names, descriptions and parameter descriptions are therefore instructions in the most literal sense. Anthropic's documentation calls extremely detailed descriptions \"by far the most important factor in tool performance\", and its Building effective agents essay, from December 2024, reports that for its SWE-bench agent the team spent more time optimising the tools than the overall prompt.",{"type":126,"content":148},[149],"The same essay names the discipline: design the agent-computer interface (ACI) with as much care as a human interface, and put yourself in the model's shoes. OpenAI's version is the intern test: could someone use the function correctly given only what the model sees? If the answer needs a conversation with you, the definition is incomplete.",{"type":138,"level":139,"id":95,"text":96},{"type":126,"content":152},[153,154,157,158,161,162,165,166,169],"The most common mistake is generating one tool per REST endpoint. Anthropic's tool-writing article from September 2025 is blunt that more tools do not always lead to better outcomes, and gives the example of a ",{"tag":130,"children":155},[156],"schedule_event"," tool that finds availability and books the meeting, instead of separate ",{"tag":130,"children":159},[160],"list_users",", ",{"tag":130,"children":163},[164],"list_events"," and ",{"tag":130,"children":167},[168],"create_event"," tools the agent has to chain. OpenAI makes the same point from the other side: combine functions that are always called in sequence, and aim for fewer than 20 functions available at the start of a turn.",{"type":171,"head":172,"rows":179},"table",[173,175,177],[174],"Endpoint-shaped",[176],"Task-shaped",[178],"Why it helps",[180,197,209,226],[181,191,195],[182,161,185,161,188],{"tag":130,"children":183},[184],"get_customer",{"tag":130,"children":186},[187],"list_orders",{"tag":130,"children":189},[190],"get_order_lines",[192],{"tag":130,"children":193},[194],"get_customer_context(customer_id)",[196],"One call returns what an agent needs to answer a support question",[198,203,207],[199,202],{"tag":130,"children":200},[201],"list_products"," + client-side filtering",[204],{"tag":130,"children":205},[206],"search_products(query, filters, limit)",[208],"Filtering happens in code, not in the context window",[210,220,224],[211,161,214,161,217],{"tag":130,"children":212},[213],"create_pr",{"tag":130,"children":215},[216],"review_pr",{"tag":130,"children":218},[219],"merge_pr",[221],{"tag":130,"children":222},[223],"pull_request(action, ...)",[225],"Anthropic's suggestion: group related actions behind an action parameter",[227,232,236],[228,231],{"tag":130,"children":229},[230],"read_logs"," (full dump)",[233],{"tag":130,"children":234},[235],"search_logs(query, since, context_lines)",[237],"Returns the relevant lines with context instead of everything",{"type":126,"content":239},[240,241,244,245,250],"Consolidation has a limit: a single ",{"tag":130,"children":242},[243],"do_anything(json)"," tool hides every decision inside one argument and makes permissions impossible. I split along risk lines. Reads can be broad; writes, payments and anything irreversible get their own tool with a narrow schema, so an approval gate as described in ",{"tag":246,"to":247,"children":248},"link","\u002Fblog\u002Fhuman-in-the-loop-ai-agents",[249],"human in the loop for AI agents"," can target them precisely.",{"type":138,"level":139,"id":98,"text":99},{"type":126,"content":253},[254,255,258,259,261,262,264,265,268,269,272,273,276],"Once an agent sees tools from several services, names collide: ",{"tag":130,"children":256},[257],"search"," from the CRM, ",{"tag":130,"children":260},[257]," from the wiki, ",{"tag":130,"children":263},[257]," from the shop. Both Anthropic sources recommend prefixing by service and resource, such as ",{"tag":130,"children":266},[267],"github_list_prs"," or ",{"tag":130,"children":270},[271],"slack_send_message",", and the tool-writing article adds that prefix versus suffix schemes measurably change results, so test yours. Technical limits are generous: the Claude API accepts names matching ",{"tag":130,"children":274},[275],"^[a-zA-Z0-9_-]{1,128}$",", and the MCP specification says names should be 1 to 128 characters, case-sensitive, unique per server, using letters, digits, underscore, hyphen and dot.",{"type":126,"content":278},[279,280,282,283,286,287,290,291,290,294,297],"Parameter names deserve the same care. Anthropic's example is small and worth copying everywhere: instead of a parameter named ",{"tag":130,"children":281},[132],", use ",{"tag":130,"children":284},[285],"user_id",". In a shop context that becomes ",{"tag":130,"children":288},[289],"sku"," versus ",{"tag":130,"children":292},[293],"article_number",{"tag":130,"children":295},[296],"product_id","; pick the one your users say, and describe the format in the parameter description.",{"type":138,"level":139,"id":101,"text":102},{"type":126,"content":300},[301],"Anthropic's checklist for a description is: what the tool does, when it should be used and when it should not, what each parameter means and how it changes behaviour, and important caveats such as what the tool does not return. It asks for at least three to four sentences per tool. The tool-writing article frames it as onboarding a new colleague: make implicit context explicit, including query formats, niche terminology and how resources relate.",{"type":130,"code":303},"{\n  \"name\": \"shop_search_products\",\n  \"description\": \"Searches the B2B catalogue by keyword, part number or attribute and returns up to `limit` matching products with name, SKU, price for the current customer and stock status. Use it when the user asks about products, availability or alternatives. Do not use it for order history (use shop_get_orders) or for prices of other customers. Exact part numbers such as 'ART-10001' match only when passed in `sku`, not in `query`. Results are sorted by relevance; if there are more, the response contains `next_cursor`.\",\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"query\": { \"type\": \"string\", \"description\": \"Free-text search in German or English, e.g. 'Edelstahl Schraube M8'\" },\n      \"sku\": { \"type\": \"string\", \"description\": \"Exact SKU, e.g. 'ART-10001'. Overrides query.\" },\n      \"in_stock_only\": { \"type\": \"boolean\", \"description\": \"Only return products available now. Default false.\" },\n      \"limit\": { \"type\": \"integer\", \"minimum\": 1, \"maximum\": 25, \"description\": \"Default 10.\" },\n      \"response_format\": { \"type\": \"string\", \"enum\": [\"concise\", \"detailed\"], \"description\": \"concise: name, SKU, price, stock. detailed: adds attributes and documents.\" }\n    },\n    \"additionalProperties\": false\n  },\n  \"input_examples\": [ { \"query\": \"Edelstahl Schraube M8\", \"in_stock_only\": true }, { \"sku\": \"ART-10001\" } ]\n}",{"type":126,"content":305},[306,307,310],"For complex inputs, the Claude API accepts ",{"tag":130,"children":308},[309],"input_examples",": an array of example inputs that must validate against the schema, otherwise the request fails with a 400. They cost roughly 20 to 50 tokens each for simple examples and 100 to 200 for nested objects. OpenAI adds a caution worth noting: examples help regular models but may hurt performance with reasoning models, so measure before keeping them.",{"type":138,"level":139,"id":104,"text":105},{"type":126,"content":313},[314],"Building effective agents borrows a term from manufacturing: poka-yoke your tools, changing the arguments so mistakes become harder. Its example is concrete. The SWE-bench agent kept getting relative file paths wrong after changing directory, so the team changed the tool to require absolute paths, and the model then used them flawlessly. The same idea in other forms:",{"type":316,"items":317},"list",[318,332,337,354],[319,323,324,327,328,331],{"tag":320,"children":321},"strong",[322],"Enums instead of free text."," OpenAI's counter-example is ",{"tag":130,"children":325},[326],"toggle_light(on: bool, off: bool)",", which allows invalid states; one ",{"tag":130,"children":329},[330],"state"," enum does not.",[333,336],{"tag":320,"children":334},[335],"Do not ask for what the code knows."," If the session already has the customer and order, inject them in code. OpenAI: do not make the model fill arguments you already know.",[338,341,342,345,346,349,350,353],{"tag":320,"children":339},[340],"Turn on strict mode."," OpenAI recommends always enabling it; it requires ",{"tag":130,"children":343},[344],"additionalProperties: false"," and every property in ",{"tag":130,"children":347},[348],"required",", with optional fields typed as nullable. On the Claude API, ",{"tag":130,"children":351},[352],"strict: true"," guarantees inputs match the schema.",[355,358],{"tag":320,"children":356},[357],"Ask for an explanation, not reasoning."," Anthropic warns that a parameter asking for the model's step-by-step reasoning may trigger a refusal; ask for a short explanation or the evidence instead.",{"type":126,"content":360},[361,362,366],"Strict schemas guarantee shape, not truth. A valid SKU format can still name a product that does not exist, which is why the server must validate and return a useful error. The guarantees and gaps of schema enforcement are covered in ",{"tag":246,"to":363,"children":364},"\u002Fblog\u002Fstructured-outputs-json-schema-llm",[365],"structured outputs with JSON Schema",".",{"type":138,"level":139,"id":107,"text":108},{"type":126,"content":369},[370,371,374],"Whatever a tool returns lands in the context window and stays there for the rest of the run. Anthropic's guidance is to return only high-signal information, and it found that resolving arbitrary alphanumeric UUIDs into meaningful names improved precision on retrieval tasks. It also suggests a ",{"tag":130,"children":372},[373],"response_format"," enum so the agent can choose: in its Slack example the detailed response used 206 tokens and the concise one 72, about a third. For anything that can be large, add pagination, range selection, filtering or truncation with sensible defaults; Claude Code, for comparison, caps tool responses at 25,000 tokens by default.",{"type":376,"attrs":377,"inner":381,"caption":382},"diagram",{"viewBox":378,"role":379,"aria-labelledby":380},"0 0 720 170","img","atd1-t atd1-d","\u003Ctitle id=\"atd1-t\">One tool call, from choice to result\u003C\u002Ftitle>\u003Cdesc id=\"atd1-d\">The model selects a tool from its name and description, fills the schema, the server validates and executes, and returns either a compact result or an instructive error the model can act on.\u003C\u002Fdesc>\u003Cdefs>\u003Cmarker id=\"atd1-ah\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\">\u003Cpath d=\"M0 0L10 5L0 10z\" class=\"d-head\" \u002F>\u003C\u002Fmarker>\u003C\u002Fdefs>\u003Crect x=\"20\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-box\" \u002F>\u003Ctext x=\"79\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Select\u003C\u002Ftext>\u003Ctext x=\"79\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">name + description\u003C\u002Ftext>\u003Cpath d=\"M138 85H158\" class=\"d-line\" marker-end=\"url(#atd1-ah)\" \u002F>\u003Crect x=\"160\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-sky\" \u002F>\u003Ctext x=\"220\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Fill\u003C\u002Ftext>\u003Ctext x=\"220\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">strict schema\u003C\u002Ftext>\u003Cpath d=\"M279 85H299\" class=\"d-line\" marker-end=\"url(#atd1-ah)\" \u002F>\u003Crect x=\"301\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-gold\" \u002F>\u003Ctext x=\"360\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Validate\u003C\u002Ftext>\u003Ctext x=\"360\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">server side\u003C\u002Ftext>\u003Cpath d=\"M419 85H439\" class=\"d-line\" marker-end=\"url(#atd1-ah)\" \u002F>\u003Crect x=\"441\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-mint\" \u002F>\u003Ctext x=\"500\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Result\u003C\u002Ftext>\u003Ctext x=\"500\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">concise, paged\u003C\u002Ftext>\u003Cpath d=\"M560 85H580\" class=\"d-line\" marker-end=\"url(#atd1-ah)\" \u002F>\u003Crect x=\"582\" y=\"47\" width=\"118\" height=\"76\" rx=\"10\" class=\"d-box d-fill-accent\" \u002F>\u003Ctext x=\"641\" y=\"81\" text-anchor=\"middle\" class=\"d-text\">Or error\u003C\u002Ftext>\u003Ctext x=\"641\" y=\"103\" text-anchor=\"middle\" class=\"d-small\">what to try next\u003C\u002Ftext>",[383],"Each box is a place where the tool designer, not the model, decides how likely the next step is to go right.",{"type":126,"content":385},[386,387,391],"Large results are also the main driver of ",{"tag":246,"to":388,"children":389},"\u002Fblog\u002Fcontext-rot-compaction-long-running-agents",[390],"context rot in long-running agents",". A tool that returns a cursor and the first ten hits is cheaper now and keeps the agent sharper fifty turns later.",{"type":138,"level":139,"id":110,"text":111},{"type":126,"content":394},[395,396,399,400,403],"A tool error is the next prompt the model reads, so write it like one. The Claude API carries execution errors as a normal ",{"tag":130,"children":397},[398],"tool_result"," with ",{"tag":130,"children":401},[402],"is_error: true",", and Anthropic's tip is specific: instead of a generic \"failed\", say what went wrong and what to try next, for example \"Rate limit exceeded. Retry after 60 seconds.\" For invalid calls such as a missing parameter, Claude retries two to three times with corrections before apologising to the user, so a precise message usually saves the run.",{"type":130,"code":405},"\u002F\u002F Bad: the model learns nothing\n{ \"type\": \"tool_result\", \"tool_use_id\": \"toolu_01\", \"is_error\": true, \"content\": \"Error 422\" }\n\n\u002F\u002F Good: what failed, why, and the next valid move\n{ \"type\": \"tool_result\", \"tool_use_id\": \"toolu_01\", \"is_error\": true,\n  \"content\": \"No product with sku 'ART-1001'. SKUs have 5 digits after 'ART-'. Closest matches: ART-10010 (Edelstahl Schraube M8), ART-10011 (M10). Call shop_search_products with sku set to one of these, or with query if the user gave a description.\" }",{"type":126,"content":407},[408,409,412],"MCP draws the same line formally. Its specification separates protocol errors, standard JSON-RPC errors for unknown tools, malformed requests and server failures, from tool execution errors reported inside the result with ",{"tag":130,"children":410},[411],"isError: true",": API failures, input validation errors such as a date in the wrong format, and business logic errors. Clients should pass execution errors to the model so it can self-correct; protocol errors are less likely to lead to recovery.",{"type":414,"variant":415,"title":416,"body":417},"callout","tip","Never return a stack trace",[418],[419],"A traceback costs hundreds of tokens, tells the model nothing actionable and can leak file paths, hostnames or secrets into a context that may be logged or exfiltrated. Log the trace on the server with the request id and return one sentence the model can use.",{"type":138,"level":139,"id":113,"text":114},{"type":126,"content":422},[423,424,427],"Connecting a few MCP servers quickly produces a hundred tools. Anthropic quantifies the cost: a typical setup with GitHub, Slack, Sentry, Grafana and Splunk can consume about 55,000 tokens of definitions before any work, and Claude's ability to pick the right tool degrades beyond 30 to 50 available tools. Its tool search tool addresses both. You send every definition, mark most with ",{"tag":130,"children":425},[426],"defer_loading: true",", and Claude searches names, descriptions and argument names by regex or BM25, loading only the matches, typically three to five, which Anthropic says cuts definition tokens by over 85 percent.",{"type":316,"items":429},[430,435,440,445],[431,434],{"tag":320,"children":432},[433],"When to switch:"," Anthropic recommends tool search with 10 or more tools, definitions above 10,000 tokens, or several MCP servers; below 10 tools that are all used every time, load them normally.",[436,439],{"tag":320,"children":437},[438],"Keep the frequent ones loaded:"," leave your three to five most used tools non-deferred.",[441,444],{"tag":320,"children":442},[443],"Write for search:"," consistent prefixes let one query match a whole service; use the words users use in descriptions.",[446,449],{"tag":320,"children":447},[448],"Cache stays intact:"," deferred tools are excluded from the prompt prefix, so discovering one does not invalidate the prompt cache.",{"type":126,"content":451},[452,453,366],"The broader choice between MCP servers, CLIs and skills for coding agents is covered in ",{"tag":246,"to":454,"children":455},"\u002Fblog\u002Fagents-md-skills-mcp-cli-decision-matrix",[456],"AGENTS.md, skills, MCP or CLI",{"type":138,"level":139,"id":116,"text":117},{"type":126,"content":459},[460,461,463],"Tool results often carry content you do not control: web pages, inbound email, uploads, third-party APIs. Anthropic's documentation tells you to treat that content as untrusted, because it may contain instructions aimed at the model, and to keep it inside ",{"tag":130,"children":462},[398]," blocks rather than in the system prompt or plain user text. The MCP specification adds that clients must treat tool annotations as untrusted unless they come from trusted servers, that servers must validate all inputs, enforce access control, rate limit invocations and sanitise outputs, and that a human should be able to deny tool invocations.",{"type":126,"content":465},[466,467,471,472,366],"In practice: put permissions in the tool implementation, not in its description; require confirmation for writes; and never combine private data, untrusted content and an outbound channel in one agent without a plan. The patterns are in ",{"tag":246,"to":468,"children":469},"\u002Fblog\u002Fprompt-injection-lethal-trifecta-patterns",[470],"the lethal trifecta and six design patterns",", and the server-side checks in the ",{"tag":246,"to":473,"children":474},"\u002Fblog\u002Fmcp-server-security-checklist",[475],"MCP security checklist",{"type":138,"level":139,"id":119,"text":120},{"type":126,"content":478},[479],"Anthropic's process is the most useful part of its tool-writing article: build a quick prototype, write realistic evaluation tasks that may need many tool calls, run them, and read the transcripts. Track total tool calls, tokens, runtime and tool errors alongside task success, and keep a held-out set so you do not overfit descriptions to your own tests. Redundant calls point to missing pagination or filters; repeated invalid arguments point to an unclear description or a schema that permits the mistake.",{"type":126,"content":481},[482,483,487,488,366],"How to grade the runs themselves, trajectories as well as outcomes, is the subject of ",{"tag":246,"to":484,"children":485},"\u002Fblog\u002Fevaluating-ai-agents-trajectories",[486],"evaluating AI agents",". For how the loop around these tools works, start with ",{"tag":246,"to":489,"children":490},"\u002Fblog\u002Fagent-loop-explained",[491],"the agent loop, explained",{"type":138,"level":139,"id":122,"text":123},{"type":316,"ordered":494,"items":495},true,[496,500,503,506,509,512,515],[497],{"tag":498,"href":38,"children":499},"a",[37],[501],{"tag":498,"href":41,"children":502},[40],[504],{"tag":498,"href":44,"children":505},[43],[507],{"tag":498,"href":47,"children":508},[46],[510],{"tag":498,"href":50,"children":511},[49],[513],{"tag":498,"href":53,"children":514},[52],[516],{"tag":498,"href":56,"children":517},[55],[519,589,637,695],{"slug":520,"published":521,"minutes":522,"category":7,"tags":523,"keywords":529,"about":541,"sources":549,"cover":583,"og":584,"expertise":59,"locales":585,"lang":61,"title":586,"description":587,"coverAlt":588},"context-rot-compaction-long-running-agents","2026-10-16",10,[524,525,526,527,528],"Context rot","Compaction","Context engineering","Long-running agents","Agent memory",[530,531,532,533,534,535,536,537,538,539,540],"context rot","context rot LLM","compaction AI agents","context engineering","long-running agents context window","Claude compaction API","context editing clear tool results","OpenAI responses compaction","lost in the middle LLM","agent context management","sub-agents context isolation",[542,545,548],{"name":543,"url":544},"Context window","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FLarge_language_model#Context_window",{"name":546,"url":547},"Attention (machine learning)","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAttention_(machine_learning)",{"name":27,"url":28},[550,553,556,559,562,565,568,571,574,577,580],{"title":551,"url":552},"Chroma: Context Rot: How Increasing Input Tokens Impacts LLM Performance (Jul 2025)","https:\u002F\u002Fresearch.trychroma.com\u002Fcontext-rot",{"title":554,"url":555},"Liu et al.: Lost in the Middle: How Language Models Use Long Contexts (2023)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2307.03172",{"title":557,"url":558},"Modarressi et al.: NoLiMa: Long-Context Evaluation Beyond Literal Matching (2025)","https:\u002F\u002Farxiv.org\u002Fabs\u002F2502.05167",{"title":560,"url":561},"Anthropic: Effective context engineering for AI agents (Sep 2025)","https:\u002F\u002Fwww.anthropic.com\u002Fengineering\u002Feffective-context-engineering-for-ai-agents",{"title":563,"url":564},"Anthropic: Effective harnesses for long-running agents (Nov 2025)","https:\u002F\u002Fwww.anthropic.com\u002Fengineering\u002Feffective-harnesses-for-long-running-agents",{"title":566,"url":567},"Claude API docs: Compaction at a token threshold","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fcompaction-threshold",{"title":569,"url":570},"Claude API docs: Compaction on demand","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fcompaction-on-demand",{"title":572,"url":573},"Claude API docs: Context editing","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fcontext-editing",{"title":575,"url":576},"Claude API docs: Memory tool","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fagents-and-tools\u002Ftool-use\u002Fmemory-tool",{"title":578,"url":579},"OpenAI API docs: Compaction","https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Fcompaction",{"title":581,"url":582},"Cognition: Don't Build Multi-Agents","https:\u002F\u002Fcognition.ai\u002Fblog\u002Fdont-build-multi-agents","\u002Fimages\u002Fblog\u002Fcontext-rot-compaction-long-running-agents\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fcontext-rot-compaction-long-running-agents\u002Fog.jpg",[61,62,63],"Context rot in long-running agents: clearing, compaction, memory and sub-agents","Why LLM accuracy drops as context grows, and how clearing tool results, compaction, notes and sub-agents keep long-running agents on track.","A small square press squeezing a tall stack of sheets into a short one, two notes branching off.",{"slug":590,"published":521,"minutes":591,"category":7,"tags":592,"keywords":597,"about":608,"sources":615,"cover":631,"og":632,"expertise":59,"locales":633,"lang":61,"title":634,"description":635,"coverAlt":636},"browser-agents-e2e-testing-playwright",7,[593,594,595,12,596],"Playwright","E2E testing","Coding agents","Test automation",[598,599,600,601,602,603,604,605,606,607],"playwright test agents","playwright planner generator healer","ai e2e testing","playwright mcp","llm generated playwright tests","self-healing tests","browser agent testing","playwright init-agents","ai test automation 2026","playwright cli skills",[609,611,614],{"name":593,"url":610},"https:\u002F\u002Fplaywright.dev\u002F",{"name":612,"url":613},"End-to-end testing","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSystem_testing",{"name":30,"url":31},[616,619,622,625,628],{"title":617,"url":618},"Playwright docs: Test agents (planner, generator, healer)","https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Ftest-agents",{"title":620,"url":621},"Microsoft: Playwright MCP README (MCP vs CLI, accessibility snapshots)","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fplaywright-mcp",{"title":623,"url":624},"Playwright docs: Best practices","https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fbest-practices",{"title":626,"url":627},"Playwright docs: Locators","https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Flocators",{"title":629,"url":630},"Browserbase: Stagehand README (act, extract, observe)","https:\u002F\u002Fgithub.com\u002Fbrowserbase\u002Fstagehand","\u002Fimages\u002Fblog\u002Fbrowser-agents-e2e-testing-playwright\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fbrowser-agents-e2e-testing-playwright\u002Fog.jpg",[61,62,63],"Browser agents for E2E testing: let agents write Playwright tests, not run them","Where AI agents help with end-to-end tests: Playwright planner, generator and healer, MCP or CLI, and the guardrails that keep healed tests honest.","Small square modules on the left handing a plain rectangle to a closed rectangular loop on the right.",{"slug":638,"published":521,"minutes":639,"category":7,"tags":640,"keywords":644,"about":656,"sources":664,"cover":689,"og":690,"expertise":59,"locales":691,"lang":61,"title":692,"description":693,"coverAlt":694},"a2a-protocol-agent-interoperability",12,[641,9,12,642,643],"A2A","Interoperability","Agent security",[645,646,647,648,649,650,651,652,653,654,655],"a2a protocol","agent2agent protocol","a2a vs mcp","a2a agent card","agent-card.json well-known","a2a protocol 1.0","a2a task lifecycle","agent to agent communication protocol","a2a security","a2a json-rpc grpc","agent session smuggling",[657,660,661],{"name":658,"url":659},"Agent2Agent protocol","https:\u002F\u002Fa2a-protocol.org\u002F",{"name":30,"url":31},{"name":662,"url":663},"Linux Foundation","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FLinux_Foundation",[665,668,671,674,677,680,683,686],{"title":666,"url":667},"A2A Protocol Specification (latest, v1.0)","https:\u002F\u002Fa2a-protocol.org\u002Flatest\u002Fspecification\u002F",{"title":669,"url":670},"A2A: a2a.proto, the normative data model (GitHub)","https:\u002F\u002Fgithub.com\u002Fa2aproject\u002FA2A\u002Fblob\u002Fmain\u002Fspecification\u002Fa2a.proto",{"title":672,"url":673},"A2A docs: A2A and MCP","https:\u002F\u002Fa2a-protocol.org\u002Flatest\u002Ftopics\u002Fa2a-and-mcp\u002F",{"title":675,"url":676},"A2A docs: Agent discovery","https:\u002F\u002Fa2a-protocol.org\u002Flatest\u002Ftopics\u002Fagent-discovery\u002F",{"title":678,"url":679},"Google Developers Blog: Announcing the Agent2Agent Protocol (Apr 2025)","https:\u002F\u002Fdevelopers.googleblog.com\u002Fen\u002Fa2a-a-new-era-of-agent-interoperability\u002F",{"title":681,"url":682},"Linux Foundation: Launch of the Agent2Agent Protocol Project (Jun 2025)","https:\u002F\u002Fwww.linuxfoundation.org\u002Fpress\u002Flinux-foundation-launches-the-agent2agent-protocol-project-to-enable-secure-intelligent-communication-between-ai-agents",{"title":684,"url":685},"Linux Foundation: A2A surpasses 150 organizations in its first year (Apr 2026)","https:\u002F\u002Fwww.linuxfoundation.org\u002Fpress\u002Fa2a-protocol-surpasses-150-organizations-lands-in-major-cloud-platforms-and-sees-enterprise-production-use-in-first-year",{"title":687,"url":688},"Unit 42: Agent Session Smuggling in Agent2Agent Systems (Oct 2025)","https:\u002F\u002Funit42.paloaltonetworks.com\u002Fagent-session-smuggling-in-agent2agent-systems\u002F","\u002Fimages\u002Fblog\u002Fa2a-protocol-agent-interoperability\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fa2a-protocol-agent-interoperability\u002Fog.jpg",[61,62,63],"The A2A protocol explained: agent cards, tasks, and where it fits next to MCP","What the Agent2Agent protocol standardizes in v1.0: agent cards, tasks, bindings, security, how it differs from MCP, and when it is worth using.","Two closed rectangular modules face each other across a gap, joined by a bridge rail with arrows running both ways.",{"slug":696,"published":697,"minutes":6,"category":7,"tags":698,"keywords":704,"about":713,"sources":723,"cover":772,"og":773,"expertise":59,"locales":774,"lang":61,"title":775,"description":776,"coverAlt":777},"ai-assisted-development-economics","2026-10-01",[699,700,701,702,703],"AI coding agents","Developer productivity","Engineering economics","Team cost","GDPR",[705,706,707,708,709,710,711,712],"AI coding agents cost","developer productivity AI study","METR AI developer slowdown","AI coding break-even cost model","one senior engineer vs team","AI coding agent vs agency","DORA AI adoption report","GDPR processor contract AI coding tools",[714,717,720],{"name":715,"url":716},"General Data Protection Regulation","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FGeneral_Data_Protection_Regulation",{"name":718,"url":719},"Randomized controlled trial","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FRandomized_controlled_trial",{"name":721,"url":722},"Bus factor","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBus_factor",[724,727,730,733,736,739,742,745,748,751,754,757,760,763,766,769],{"title":725,"url":726},"METR: early-2025 AI and experienced open-source developers","https:\u002F\u002Fmetr.org\u002Fblog\u002F2025-07-10-early-2025-ai-experienced-os-dev-study\u002F",{"title":728,"url":729},"Becker et al.: arXiv 2507.09089","https:\u002F\u002Farxiv.org\u002Fabs\u002F2507.09089",{"title":731,"url":732},"METR: developer productivity experiment design, February 2026","https:\u002F\u002Fmetr.org\u002Fblog\u002F2026-02-24-uplift-update\u002F",{"title":734,"url":735},"Peng et al.: GitHub Copilot controlled experiment, arXiv 2302.06590","https:\u002F\u002Farxiv.org\u002Fhtml\u002F2302.06590v1",{"title":737,"url":738},"Cui et al.: three field experiments with software developers","https:\u002F\u002Fwww.microsoft.com\u002Fen-us\u002Fresearch\u002F?p=1148213",{"title":740,"url":741},"DORA: State of AI-assisted Software Development 2025","https:\u002F\u002Fresearch.google\u002Fpubs\u002Fdora-2025-state-of-ai-assisted-software-development-report\u002F",{"title":743,"url":744},"Google Cloud: highlights from the 2024 DORA report","https:\u002F\u002Fcloud.google.com\u002Fblog\u002Fproducts\u002Fdevops-sre\u002Fannouncing-the-2024-dora-report",{"title":746,"url":747},"Stack Overflow: Developer Survey 2025, AI","https:\u002F\u002Fsurvey.stackoverflow.co\u002F2025\u002Fai",{"title":749,"url":750},"Ziftci et al.: Migrating Code At Scale With LLMs At Google","https:\u002F\u002Farxiv.org\u002Fabs\u002F2504.09691",{"title":752,"url":753},"Alshahwan et al.: Automated Unit Test Improvement using Large Language Models at Meta","https:\u002F\u002Farxiv.org\u002Fabs\u002F2402.09171",{"title":755,"url":756},"GitClear: AI Copilot Code Quality: 2025 Look Back at 12 Months of Data","https:\u002F\u002Fwww.gitclear.com\u002Fai_assistant_code_quality_2025_research",{"title":758,"url":759},"GDPR, Regulation (EU) 2016\u002F679, Article 28","https:\u002F\u002Feur-lex.europa.eu\u002Feli\u002Freg\u002F2016\u002F679\u002Foj\u002Feng",{"title":761,"url":762},"Anthropic: Commercial Terms of Service","https:\u002F\u002Fwww.anthropic.com\u002Flegal\u002Fcommercial-terms",{"title":764,"url":765},"Claude: pricing","https:\u002F\u002Fclaude.com\u002Fpricing",{"title":767,"url":768},"Claude Platform: data residency","https:\u002F\u002Fplatform.claude.com\u002Fdocs\u002Fen\u002Fbuild-with-claude\u002Fdata-residency",{"title":770,"url":771},"GitHub Copilot: plans and pricing","https:\u002F\u002Fgithub.com\u002Ffeatures\u002Fcopilot\u002Fplans","\u002Fimages\u002Fblog\u002Fai-assisted-development-economics\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fai-assisted-development-economics\u002Fog.jpg",[61,62,63],"One senior with coding agents versus a team: what the evidence says","The METR, DORA, Microsoft and GitHub studies on AI coding tools, what they do not prove, and a break-even cost model for one senior versus a team or agency.","A level balance with three small squares in one pan and one larger rectangle in the other, resting on a square pivot.",1792222776056]