{"slug": "beyond-chat-architecting-intelligence-with-skills-and-specification-engineering", "title": "Beyond \"Chat\": Architecting Intelligence with Skills and Specification Engineering", "summary": "A developer argues that the industry's reliance on 'Mega-Prompts' is a technical dead end, advocating instead for a shift from prompt engineering to context engineering. The approach, demonstrated through work on the Vibrisse Agent, uses XML tagging to separate instructions from context and employs 'good vs bad' examples to stabilize output, especially for edge AI models running in the browser.", "body_md": "Remember the days when we used to dump all our CSS and JavaScript into a single `index.html`\n\nfile? That's exactly what a \"Mega-Prompt\" is today: an unmanageable monolith.\n\nA few weeks ago, while working on the orchestration of [ Vibrisse Agent](https://github.com/QuentinMerle/vibrisse-agent) (my local AI agent), I hit this exact wall. I was trying to stabilize a complex task by adding instructions to a 500-line system prompt. The more rules I added, the more the model forgot the older ones.\n\nThe industry has sold us the myth of the Mega-Prompt. Those famous \"50 ultimate prompts\" or massive blocks of incantatory text are a technical dead end. Creative writing doesn't scale in production.\n\nAs a web developer, my conviction is simple: to build reliable applications, we must stop \"talking\" to the machine and start **configuring** it. This is the shift from Prompt Engineering to **Context Engineering**.\n\nThe first mistake with LLMs is mixing instructions (the logic) and context (the data) into an unstructured stream of text. It's the cognitive equivalent of spaghetti code.\n\nThe solution? A strict separation of concerns. A highly effective technique (documented by Anthropic, but applicable to any model, including local SLMs), is **XML Tagging**.\n\nHere is the \"dirty\" approach (classic chat):\n\n```\nYou are a security expert. Analyze this authentication code, be strict, don't write a summary, check for XSS and SQLi vulnerabilities. Here is the code: function login() { ... }\n```\n\nAnd here is the \"engineering\" approach:\n\n```\n<role>Application Security Expert</role>\n\n<instructions>\n1. Analyze the code provided in <context>.\n2. Identify vulnerabilities (focus: XSS, SQLi).\n3. Do not produce an introductory summary.\n</instructions>\n\n<context>\nfunction login() { ... }\n</context>\n```\n\nTyping the language via tags creates clear boundaries. The model knows exactly where the directive is and where the data is.\n\nEven with clear instructions, AI can drift in output format or tone. This is where managing by examples (*exemplars*) comes into play.\n\nGiving the AI a concrete example of the expected behavior (Good Example) versus the behavior to avoid (Bad Example) is often much more powerful and token-efficient than adding 15 lines of theoretical instructions.\n\nSimply add an examples section to your XML structure:\n\n```\n<examples>\n  <example>\n    <input>Review of Button.tsx component</input>\n    <good_output>Line 42: The `aria-label` attribute is missing for accessibility.</good_output>\n    <bad_output>This component is really well written, good job. However, accessibility could be improved.</bad_output>\n    <reasoning>The good example is surgical and actionable. The bad example is wordy and subjective.</reasoning>\n  </example>\n</examples>\n```\n\nThis \"Good vs Bad + Explanation\" pattern acts as a behavioral safeguard. This is especially critical in Edge AI. If you run a small 3B parameter model directly in the browser (e.g., our demonstrator ** Vans** using\n\n`window.ai`\n\nand `@mlc-ai/web-llm`\n\n), the model has reduced reasoning capabilities. Providing an XML \n\n``` js\n// Example of an Edge AI call via window.ai\nconst response = await window.ai.createTextSession().prompt(`\n  <instructions>Analyze the accessibility of this component according to WCAG standards.</instructions>\n  <examples>...</examples>\n  <context>${domNode.outerHTML}</context>\n`);\n```\n\n💡\n\nThe Craftsman's Tip:Treat your prompt like a configuration file. If your overall context exceeds 200 lines, it's no longer a prompt, it's a monolith. It's time to break it down.\n\nThis is where the concept of **Skill** comes in. As the IBM team explains very well, we must distinguish semantic memory (facts, often managed via RAG) from procedural memory (the *how*).\n\nThink of an LLM as an airplane pilot. The pilot intrinsically knows how to fly (reasoning capabilities). But before taking off, they need the specific checklist for their aircraft (the Skill) so they don't crash. You don't hand a Boeing 747 manual to a Cessna pilot.\n\nInstead of loading all your agent's capabilities into a single prompt, the idea is to encapsulate each capability into a **Skill**. A modern Skill is no longer just a simple text file; it's a true versionable \"plugin\". It generally takes the form of a folder containing a main instructions file (`SKILL.md`\n\nwith its Front Matter, a standard pushed by *agentskills.io*), but also potentially business scripts and reference examples.\n\nHere is the typical anatomy of a Skill's central `SKILL.md`\n\nfile:\n\n```\n---\nname: obsidian-researcher\ndescription: Trigger this skill to search for information in the user's Obsidian vault.\ntools:\n  - mcp_obsidian_search\n  - mcp_obsidian_read_note\n---\n\n# Instructions\n1. Use the `mcp_obsidian_search` tool with the user's query.\n2. If a file seems relevant, read it using `mcp_obsidian_read_note`.\n3. Synthesize the notes found, without inventing facts (use quotes).\n```\n\nNotice the `tools`\n\nkey in the Front Matter. This is one of the most powerful concepts in Specification Engineering: **tool scoping**.\n\nRather than giving your AI agent global access to 50 tools (which increases the attack surface and dilutes the model's attention), you restrict its arsenal to what is strictly necessary *for this specific task*. The skill becomes the secure entry point to an external MCP server, a local Python script, or a simple URL.\n\nThis **Progressive Disclosure** approach (revealing information to the model only when strictly necessary) is vital in local AI. When you run a Llama 3 or a Gemma on your own hardware, every token counts. Loading only the procedural \"brain\" relevant to the context saves VRAM, speeds up inference, and drastically reduces hallucinations.\n\nA good Skill is a step-by-step procedure you could hand to a human intern. If the human doesn't understand, the AI will hallucinate.\n\nWhile Skills act as on-demand procedural memory, the agent still needs an identity and global rules. This is where structure files come into play:\n\n`AGENTS.md`\n\n: Defines the agent's identity, tone, and scope. This is the root context.`DESIGN.md`\n\n: Casts your absolute standards in stone. For example, instead of repeating \"write accessible code\" in every skill, your `DESIGN.md`\n\nstipulates the A11Y rules or performance constraints (e.g., 60fps) that apply everywhere.The agent then becomes a conductor. Faced with a request, it combines its `AGENTS.md`\n\n, its `DESIGN.md`\n\n, then dynamically selects the right `SKILL.md`\n\n(loading it into active context), and executes it, often by calling external tools via the **Model Context Protocol (MCP)**.\n\nBut the greatest advantage of this entirely file-based architecture is **governance**.\n\nUpdating your AI's behavior is no longer a nebulous conversation lost in a chat history. It's a **Pull Request**. You can run a `git diff`\n\nbetween two versions of an AI procedure. For an engineering team, this is the ultimate argument for security and maintainability. This is exactly the approach we favor on our projects to manage complex behaviors without losing control.\n\nIf we claim that AI behaviors are code, we must follow through with the engineering process. Two pillars are missing to close the loop:\n\n**1. Structured Output (JSON Schema) and Function Models:** A skill must act like an API. If the AI politely responds \"Here is your result: { ... }\", it breaks your pipeline. In local AI, the prompt is not enough. You must constrain the SLM's generation (via *Outlines*, *XGrammar*, or Ollama's native JSON mode) to mathematically guarantee that the output will respect your schema. The agent no longer generates free text; it produces deterministic data.\n\nFurthermore, the industry is now moving towards the use of **Function Models** (like *FunctionGemma* or the *Hermes* series). These models are specifically trained not to converse, but to parse parameters, call tools, and return valid JSON. It's the logical evolution: the language model becomes a simple API execution engine.\n\nFor example, on our narrative RPG engine ** GemMaster**, instead of a theoretical action schema, here is how we force the model to generate our NPCs in a strict format expected by the game:\n\n```\n# GemMaster: Force strict JSON response for NPC creation\nschema = {\n  \"type\": \"array\",\n  \"items\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"name\": { \"type\": \"string\" },\n      \"class\": { \"type\": \"string\" },\n      \"background\": { \"type\": \"string\" }\n    },\n    \"required\": [\"name\", \"class\", \"background\"]\n  }\n}\n\nresponse = generate(\n    model=\"google/gemma-2-9b-it\", # Exact model to capture indexing\n    prompt=skill_context,\n    format=schema # The sampler rejects any token outside the schema\n)\n```\n\n**2. Systematic Evaluation (Evals):** You don't approve a Pull Request on a Skill based on a \"gut feeling\". Evaluating agents has become a discipline in its own right (*LLMOps*). A behavior modification must strictly pass regression tests before being merged. Tools like `promptfoo`\n\nallow you to run your agent against a test dataset and evaluate (assert) whether the new skill regresses on edge cases.\n\nIt is this rigor that separates \"magical\" prototyping from industrial production deployment.\n\nOur profession as web developers is evolving. We will write fewer isolated functions and architect more behaviors.\n\n**To summarize:**\n\n`index.html`\n\n). Type your prompts with `SKILL.md`\n\n) with strictly scoped tools.`AGENTS.md`\n\nand `DESIGN.md`\n\n.Local AI coupled with a strict architecture allows us to maintain total control over our business logic: zero API costs, no data leaking to the cloud, and absolute sovereignty. Cloud AI remains exceptional, but for critical business workflows where predictability is king, execution control takes precedence.\n\nMagic doesn't exist in software engineering. There is only structure.\n\nAnd you, how do you version your agents' behaviors? Are you still stuck in the nightmare of mega-prompt maintenance, or have you started the transition towards skill orchestration?\n\n*Proudly developed in Beauce, Québec 🇨🇦. Interested in the alliance between immersive web engineering and local AI sovereignty? Let's connect via Vibrisse Studio!*", "url": "https://wpnews.pro/news/beyond-chat-architecting-intelligence-with-skills-and-specification-engineering", "canonical_source": "https://dev.to/quentin_merle/beyond-chat-architecting-intelligence-with-skills-and-specification-engineering-3mpm", "published_at": "2026-07-23 00:21:28+00:00", "updated_at": "2026-07-23 00:29:02.885451+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-agents", "developer-tools"], "entities": ["Vibrisse Agent", "Anthropic", "IBM", "Vans", "window.ai", "@mlc-ai/web-llm"], "alternates": {"html": "https://wpnews.pro/news/beyond-chat-architecting-intelligence-with-skills-and-specification-engineering", "markdown": "https://wpnews.pro/news/beyond-chat-architecting-intelligence-with-skills-and-specification-engineering.md", "text": "https://wpnews.pro/news/beyond-chat-architecting-intelligence-with-skills-and-specification-engineering.txt", "jsonld": "https://wpnews.pro/news/beyond-chat-architecting-intelligence-with-skills-and-specification-engineering.jsonld"}}