<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ntty</title>
    <description>The latest articles on DEV Community by Ntty (@ntty).</description>
    <link>https://dev.to/ntty</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3781917%2F59cbac53-d413-4b6d-91d4-eba3dffb6f91.jpeg</url>
      <title>DEV Community: Ntty</title>
      <link>https://dev.to/ntty</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ntty"/>
    <language>en</language>
    <item>
      <title>Stop Letting AI Write Your Entire Component</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Mon, 13 Jul 2026 11:00:07 +0000</pubDate>
      <link>https://dev.to/ntty/stop-letting-ai-write-your-entire-component-280</link>
      <guid>https://dev.to/ntty/stop-letting-ai-write-your-entire-component-280</guid>
      <description>&lt;p&gt;I spent the last three months using an AI-first editor. At first, it felt like a superpower. I could hit a keyboard shortcut, describe a feature, and watch 50 lines of React code appear. It felt fast. Then, the bugs started hitting.&lt;/p&gt;

&lt;p&gt;I realized I had developed a dangerous habit: I was accepting code I did not fully understand. When a production bug appeared in a component written by the AI, I spent forty minutes trying to figure out the logic because I had not actually written it. I was the reviewer of my own code, but I was a lazy reviewer.&lt;/p&gt;

&lt;p&gt;Here is how I changed my workflow to actually stay in control.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trap of the Big Prompt
&lt;/h2&gt;

&lt;p&gt;The biggest mistake is asking for a whole feature in one go. If you prompt "Build me a paginated table with sorting and filtering," the AI will give you a massive block of code. It will look correct. It will probably work on the first run. &lt;/p&gt;

&lt;p&gt;But that code is a black box. It often includes unnecessary dependencies, weird edge-case handling that doesn't fit your project, or outdated API patterns. When you accept a 100-line diff, you are essentially signing a contract to maintain 100 lines of logic you did not architect.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Atomic Prompting Method
&lt;/h2&gt;

&lt;p&gt;Instead of big blocks, I moved to atomic prompts. I break the task down into the smallest possible logical units. &lt;/p&gt;

&lt;p&gt;First, I define the types or the interface. I prompt for the TypeScript definition only. I review it. I tweak it. Once the data shape is locked in, I move to the next step.&lt;/p&gt;

&lt;p&gt;Next, I prompt for a single helper function. For example, "Write a function to sort this specific array of objects by date." I test that function in isolation. &lt;/p&gt;

&lt;p&gt;Finally, I ask the AI to wire these pieces into the UI. By the time the component is finished, I already understand every helper function and every type definition because I guided the process step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the AI as a Rubber Duck, Not a Ghostwriter
&lt;/h2&gt;

&lt;p&gt;I started using the chat feature differently. Instead of saying "Fix this bug," I now say "Explain why this bug might be happening and give me three possible directions to investigate." &lt;/p&gt;

&lt;p&gt;This forces my brain to stay engaged. If the AI just gives me the fix, my brain switches off. If the AI gives me the theory, I still have to do the work of implementing the solution. This is where the actual learning happens. If you stop solving problems, your skills will atrophy. You become a prompt engineer, which is a fancy way of saying you are a middleman between a requirement and a machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code Review Rule
&lt;/h2&gt;

&lt;p&gt;I implemented a personal rule: I cannot commit any AI-generated code until I can explain every single line to a hypothetical junior developer. &lt;/p&gt;

&lt;p&gt;If there is a regex pattern the AI generated that looks like magic, I do not accept it. I ask the AI to break down the regex. I test it against a few strings. Once I understand the magic, I commit it. &lt;/p&gt;

&lt;p&gt;This slows down the initial development speed, but it drastically reduces the time spent in the debugging phase. Speed is a lie if it leads to technical debt that you cannot navigate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concrete Takeaways
&lt;/h2&gt;

&lt;p&gt;If you are using an AI editor, try these three things this week:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Limit your diffs. If an AI suggests more than 20 lines of change at once, break your prompt into smaller pieces.&lt;/li&gt;
&lt;li&gt;Prompt for the "Why" before the "How". Ask for the logic or the plan before you ask for the code.&lt;/li&gt;
&lt;li&gt;Manual Refactor. After the AI generates a working solution, manually rename variables or restructure a loop to fit your style. This forces you to read the code carefully.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI is a great tool for removing boilerplate, but it is a terrible architect. Keep the architecture in your head, and use the AI to fill in the gaps.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
      <category>react</category>
    </item>
    <item>
      <title>Stop Prompting and Start Engineering: Treating LLMs as Unreliable Functions</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Sun, 12 Jul 2026 11:00:48 +0000</pubDate>
      <link>https://dev.to/ntty/stop-prompting-and-start-engineering-treating-llms-as-unreliable-functions-12fp</link>
      <guid>https://dev.to/ntty/stop-prompting-and-start-engineering-treating-llms-as-unreliable-functions-12fp</guid>
      <description>&lt;p&gt;Most developers start with AI by writing a long prompt and hoping the model returns a valid JSON object. This works 80 percent of the time. In production, that 20 percent failure rate is a disaster. It leads to runtime errors, broken UI components, and endless debugging sessions where you try to "tweak the wording" of a prompt to fix a bug.&lt;/p&gt;

&lt;p&gt;I spent three months building a feature that relied on an LLM to categorize user feedback. Every time I updated the prompt to fix one edge case, it broke two other things. I realized I was treating the AI as a magic box rather than a software component. &lt;/p&gt;

&lt;p&gt;Here is how to move from guessing to engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fallacy of the Perfect Prompt
&lt;/h2&gt;

&lt;p&gt;Prompt engineering is often sold as a way to get the perfect answer. But LLMs are probabilistic, not deterministic. Even with the temperature set to zero, you cannot guarantee a consistent output format across different model versions or high-load periods. &lt;/p&gt;

&lt;p&gt;If your code assumes the AI will always return a specific key in a JSON object, your code is fragile. You are essentially calling a function that might change its return type at any moment without warning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing the Wrapper Pattern
&lt;/h2&gt;

&lt;p&gt;Instead of trusting the output, build a validation layer between the LLM and your business logic. Treat the LLM output as "untrusted user input."&lt;/p&gt;

&lt;p&gt;First, define a strict schema for what you expect. Use a library like Zod or Pydantic to validate the response immediately after it arrives. If the validation fails, do not let the data reach your database or your frontend. &lt;/p&gt;

&lt;p&gt;Second, implement a retry loop with a fallback. If the LLM returns a malformed response, send the error message back to the LLM and ask it to fix the specific formatting error. This is far more effective than just retrying the same prompt three times.&lt;/p&gt;

&lt;h2&gt;
  
  
  Constraining the Output Space
&lt;/h2&gt;

&lt;p&gt;One of the biggest mistakes is asking the AI to "describe" something. Descriptions are variable. Instead, force the AI to choose from a predefined list of enums.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
"Categorize this feedback as positive, negative, or neutral."&lt;/p&gt;

&lt;p&gt;Try:&lt;br&gt;
"Categorize this feedback. You must choose exactly one value from this list: [POSITIVE, NEGATIVE, NEUTRAL]. Do not include any other text in your response."&lt;/p&gt;

&lt;p&gt;By limiting the output space, you make the validation layer simpler and the results more predictable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing for Regressions
&lt;/h2&gt;

&lt;p&gt;How do you know if a prompt change actually improved the system? You cannot rely on a few manual tests. You need a golden dataset.&lt;/p&gt;

&lt;p&gt;Create a JSON file containing 50 to 100 examples of inputs and the expected outputs. Every time you change a prompt, run your entire dataset through the model. If you fix the "edge case" but change five other correct answers to incorrect ones, your prompt is a regression. &lt;/p&gt;

&lt;p&gt;This turns prompt engineering into a measurable process. You are no longer guessing if it feels "better." You have a percentage accuracy score.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concrete Takeaway
&lt;/h2&gt;

&lt;p&gt;Stop trying to write the perfect prompt. It does not exist. Instead, build a system that expects the AI to fail. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Validate every response against a strict schema.&lt;/li&gt;
&lt;li&gt;Use enums to limit the output range.&lt;/li&gt;
&lt;li&gt;Build a test suite of inputs and expected outputs to track regressions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When you treat the LLM as an unreliable function, you can build reliable software around it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Stop Treating LLM Prompts Like Magic Spells</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Sat, 11 Jul 2026 11:00:48 +0000</pubDate>
      <link>https://dev.to/ntty/stop-treating-llm-prompts-like-magic-spells-1c6d</link>
      <guid>https://dev.to/ntty/stop-treating-llm-prompts-like-magic-spells-1c6d</guid>
      <description>&lt;p&gt;I spent the first few months of the AI boom treating prompts like magic spells. I would tweak a word here, add 'think step by step' there, and hope for the best. When it worked, I felt like a wizard. When it broke in production, I had no idea why.&lt;/p&gt;

&lt;p&gt;If you are building features that rely on Large Language Models (LLMs), you need to stop guessing. Prompting is not a mystical art. It is a configuration problem. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With 'Vibe-Based' Development
&lt;/h2&gt;

&lt;p&gt;Most developers start with a single long string in a variable. They send it to the API, look at the output, and manually edit the string until the output looks right. This is vibe-based development. &lt;/p&gt;

&lt;p&gt;The issue is that LLMs are non-deterministic. A prompt that works for one edge case might fail for another. If your prompt is a 500-word block of text, changing one sentence to fix a bug in the 'user profile' logic might accidentally break the 'password reset' logic. &lt;/p&gt;

&lt;h2&gt;
  
  
  Moving Toward a Systematic Approach
&lt;/h2&gt;

&lt;p&gt;To build reliable software, you need to treat your prompts like code. Here is the framework I use now.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Separate Instructions from Data
&lt;/h3&gt;

&lt;p&gt;Stop concatenating strings. Use clear delimiters. If you are passing a user's document for analysis, do not just slap it at the end of the prompt. Wrap it in XML-style tags or clear markers.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
"Summarize this text: [text]"&lt;/p&gt;

&lt;p&gt;Use:&lt;br&gt;
"Summarize the content found between the  tags.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
[text]&lt;br&gt;
"&lt;/p&gt;

&lt;p&gt;This prevents prompt injection and helps the model distinguish between your instructions and the data it is processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Implement Few-Shot Prompting
&lt;/h3&gt;

&lt;p&gt;Asking a model to "be professional" is useless. Professional means different things to different people. Instead, give it three to five examples of exactly what you want. &lt;/p&gt;

&lt;p&gt;Provide a pattern:&lt;br&gt;
Input: [Example 1]&lt;br&gt;
Output: [Example 1 Result]&lt;/p&gt;

&lt;p&gt;Input: [Example 2]&lt;/p&gt;

&lt;p&gt;By providing concrete examples, you reduce the variance in the output. You are essentially giving the model a template to follow rather than asking it to imagine a style from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Enforce Structured Output
&lt;/h3&gt;

&lt;p&gt;Parsing raw text with regex is a nightmare. If you need data to flow into a database or a UI, force the model to return JSON. &lt;/p&gt;

&lt;p&gt;Do not just ask for JSON. Define the schema. Tell the model: "Return a JSON object with the keys 'status' (string), 'id' (integer), and 'summary' (string). Do not include any conversational filler or markdown formatting."&lt;/p&gt;

&lt;p&gt;Most modern APIs have a 'JSON mode' or 'Tool calling' feature. Use them. They move the validation from the prompt level to the API level, which is much more stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Importance of a Golden Dataset
&lt;/h2&gt;

&lt;p&gt;This is the part most people skip. You cannot improve what you cannot measure. &lt;/p&gt;

&lt;p&gt;Create a 'Golden Dataset'. This is a simple JSON file containing 20 to 50 pairs of inputs and the ideal expected outputs. Every time you change a prompt, run your entire dataset through the model. &lt;/p&gt;

&lt;p&gt;If you fix a bug for case #4 but break case #12, you will know immediately. You can use a second LLM to grade the results or do manual spot checks. This turns your prompt engineering into a regression test suite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concrete Takeaway
&lt;/h2&gt;

&lt;p&gt;Stop treating your prompt as a single string. Treat it as a versioned asset. Separate your instructions from your data using tags, provide 3-5 concrete examples, and validate every change against a fixed set of test cases. &lt;/p&gt;

&lt;p&gt;When you move from 'I think this works' to 'I know this works for these 50 cases', your AI features actually become production-ready.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>programming</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Why Your SaaS Database Schema Will Break at 10k Users</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Fri, 10 Jul 2026 11:00:49 +0000</pubDate>
      <link>https://dev.to/ntty/why-your-saas-database-schema-will-break-at-10k-users-3pkd</link>
      <guid>https://dev.to/ntty/why-your-saas-database-schema-will-break-at-10k-users-3pkd</guid>
      <description>&lt;p&gt;I spent two years building a SaaS product where I thought I was being clever with my database design. I used a single shared table for everything and just slapped a &lt;code&gt;tenant_id&lt;/code&gt; column on every single row. It worked great during the beta. It worked great for the first 500 users. Then we hit a growth spurt, and the system started crawling.&lt;/p&gt;

&lt;p&gt;If you are building a multi-tenant app, you probably started with the same pattern. It is the easiest way to get to market. But there are specific walls you will hit that no amount of "upgrading the server" will fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Indexing Trap
&lt;/h2&gt;

&lt;p&gt;When you have a &lt;code&gt;tenant_id&lt;/code&gt; on every table, your instinct is to create a composite index on &lt;code&gt;(tenant_id, id)&lt;/code&gt; or &lt;code&gt;(tenant_id, created_at)&lt;/code&gt;. For a while, this is fast. But as your table grows to millions of rows, those indexes become massive. &lt;/p&gt;

&lt;p&gt;One specific problem I ran into was index fragmentation. Because data for different tenants is interleaved in the same physical storage, the database spends more time jumping around the disk than actually reading data. You end up with high IOPS and slow queries even when the result set is small.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Danger of 'The Big Table'
&lt;/h2&gt;

&lt;p&gt;In a SaaS, you usually have one or two tables that grow 100x faster than others. For me, it was the &lt;code&gt;audit_logs&lt;/code&gt; table. &lt;/p&gt;

&lt;p&gt;Because every single action by every single user in every single tenant went into one table, the index for that table eventually exceeded the available RAM. Once the index no longer fits in memory, every single query triggers a disk read. Your API response times go from 50ms to 2 seconds overnight.&lt;/p&gt;

&lt;p&gt;If you are seeing this, stop trying to optimize the query. You need to partition your data. Whether you use PostgreSQL partitioning or move those logs to a different storage engine, you cannot keep a trillion rows of audit logs in a single flat table.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 'Noisy Neighbor' Problem
&lt;/h2&gt;

&lt;p&gt;This is the part they do not tell you in tutorials. In a shared schema, one huge client can kill the experience for everyone else. &lt;/p&gt;

&lt;p&gt;I had one customer who uploaded 50,000 records via a CSV import. Their queries started scanning huge chunks of the index. Because the database was working so hard to serve that one tenant, the CPU spiked to 100 percent. Suddenly, the 50 small customers who only had 10 records each were seeing timeouts. &lt;/p&gt;

&lt;p&gt;When you share a database, you share the resources. If you do not implement rate limiting at the application level or use database-level resource quotas, your biggest customer will accidentally become your biggest liability.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Fix It Before It Breaks
&lt;/h2&gt;

&lt;p&gt;If you are still early, you do not need to move to a "database per tenant" model. That adds massive overhead for migrations and backups. Instead, try these three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Strict Query Scoping&lt;/strong&gt;: Wrap your database calls in a way that makes it impossible to forget the &lt;code&gt;tenant_id&lt;/code&gt; filter. If you forget it once, you have a massive security leak where one user sees another user's data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early Partitioning&lt;/strong&gt;: If you have a table that grows linearly with usage (like logs or events), partition it by time or by tenant ID from day one. It is much easier to start with partitions than to migrate a 500GB table later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Read Replicas for Analytics&lt;/strong&gt;: Never let your users run "Export all data to CSV" queries on your primary write database. Route those heavy, scanning queries to a read replica. This prevents a single heavy report from locking tables and freezing the app for everyone.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Concrete Takeaway
&lt;/h2&gt;

&lt;p&gt;Do not assume a shared schema scales linearly. The moment your indexes stop fitting in RAM, your performance will fall off a cliff. Monitor your buffer cache hit ratio and identify your fastest-growing tables now. If a table is growing by millions of rows a month, plan your partitioning strategy today, not when the site goes down.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Stop Building Chatbots and Start Building Agentic Workflows</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Thu, 09 Jul 2026 11:00:56 +0000</pubDate>
      <link>https://dev.to/ntty/stop-building-chatbots-and-start-building-agentic-workflows-5be5</link>
      <guid>https://dev.to/ntty/stop-building-chatbots-and-start-building-agentic-workflows-5be5</guid>
      <description>&lt;h2&gt;
  
  
  The Trap of the Single Prompt
&lt;/h2&gt;

&lt;p&gt;Most developers start their AI journey by building a 'wrapper'. You take a user input, wrap it in a system prompt, send it to an LLM, and return the result. If the result is wrong, you try to 'prompt engineer' your way out of it by adding more instructions to that single prompt.&lt;/p&gt;

&lt;p&gt;This is a dead end. No matter how good your prompt is, LLMs struggle with complex tasks in a single pass. They hallucinate, they skip steps, and they fail to double check their own work. &lt;/p&gt;

&lt;p&gt;Agentic workflows are different. Instead of one long prompt, you break the task into a loop of smaller, specialized steps where the LLM can reason, act, and correct itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Linear to Iterative
&lt;/h2&gt;

&lt;p&gt;In a standard chatbot, the flow is: User -&amp;gt; Prompt -&amp;gt; LLM -&amp;gt; Output. &lt;/p&gt;

&lt;p&gt;In an agentic workflow, the flow looks more like: User -&amp;gt; Planner -&amp;gt; Executor -&amp;gt; Critic -&amp;gt; Refiner -&amp;gt; Output.&lt;/p&gt;

&lt;p&gt;Think of it like a professional software project. You do not just write 1,000 lines of code in one go and push to production. You write a draft, you run tests, you find bugs, and you fix them. That is exactly how you should structure your LLM calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Patterns That Actually Work
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The Reflection Pattern
&lt;/h3&gt;

&lt;p&gt;This is the simplest agentic move. You ask the LLM to generate a response, and then you send that response back to the LLM (or a different model) with a prompt like: "Review the response above for technical errors or missing requirements. List the flaws."&lt;/p&gt;

&lt;p&gt;Once you have the critique, you send both the original response and the critique back to the model to generate a final version. This almost always produces a higher quality result than a single prompt, especially for coding tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Tool-Use Loops (ReAct)
&lt;/h3&gt;

&lt;p&gt;Instead of hoping the LLM knows the answer, give it tools. A tool is just a function the LLM can choose to call. &lt;/p&gt;

&lt;p&gt;The pattern works like this: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The model thinks about what it needs (Thought).&lt;/li&gt;
&lt;li&gt;It decides which tool to call (Action).&lt;/li&gt;
&lt;li&gt;Your code executes that tool and feeds the result back to the model (Observation).&lt;/li&gt;
&lt;li&gt;The model repeats this until it has enough information to answer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This prevents the model from guessing. If it needs a current stock price or a specific database record, it fetches it rather than hallucinating a plausible-looking number.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Multi-Agent Delegation
&lt;/h3&gt;

&lt;p&gt;When a task is too large, a single agent gets confused. The context window gets cluttered with irrelevant details. The solution is to split the roles. &lt;/p&gt;

&lt;p&gt;Create a 'Manager' agent that breaks the goal into sub-tasks. Then, assign those tasks to 'Worker' agents. For example, one agent handles API documentation, another handles implementation, and a third handles testing. The Manager collects the outputs and ensures they align.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hard Part: State Management
&lt;/h2&gt;

&lt;p&gt;Moving to agentic workflows introduces a new problem: state. You are no longer managing a single request, but a conversation history that includes thoughts, tool outputs, and critiques.&lt;/p&gt;

&lt;p&gt;If you do not manage this carefully, your token costs will explode, or the model will lose the original goal. I recommend using a structured state object (like a JSON store) rather than just appending everything to a chat history string. Keep track of: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The original goal&lt;/li&gt;
&lt;li&gt;The current step in the plan&lt;/li&gt;
&lt;li&gt;The history of tool calls&lt;/li&gt;
&lt;li&gt;The latest critique&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Concrete Takeaway
&lt;/h2&gt;

&lt;p&gt;Stop trying to write the 'perfect prompt'. It does not exist. &lt;/p&gt;

&lt;p&gt;If your LLM is failing at a task, do not add more adjectives to the prompt. Instead, split the task into two steps: one to generate a draft and one to critique it. Then, feed that critique back in for a second pass. &lt;/p&gt;

&lt;p&gt;Moving from a linear pipeline to an iterative loop is the single biggest jump in quality you can make in AI development.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
    </item>
    <item>
      <title>Stop treating LLMs like databases</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Wed, 08 Jul 2026 11:00:21 +0000</pubDate>
      <link>https://dev.to/ntty/stop-treating-llms-like-databases-47l1</link>
      <guid>https://dev.to/ntty/stop-treating-llms-like-databases-47l1</guid>
      <description>&lt;p&gt;I spent three months building a feature where an LLM handled our internal documentation queries. I fed it a massive system prompt containing our API specs and a few dozen examples. For the first week, it felt like magic. Then, we updated one endpoint in our API, and the bot started hallucinating old parameters and confidentially lying to our users.&lt;/p&gt;

&lt;p&gt;That was the moment I realized I was treating the LLM like a database. It is not a database. It is a reasoning engine. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Knowledge Cutoff Trap
&lt;/h2&gt;

&lt;p&gt;When you put data inside a prompt, you are using the model's context window as temporary RAM. This is expensive and fragile. The biggest issue is that LLMs are probabilistic, not deterministic. If you ask a SQL database for a user's email, you get the exact string stored in that row. If you ask an LLM for a detail buried in a 5,000 word prompt, it might get it right 95% of the time, but that 5% failure rate is where the bugs live.&lt;/p&gt;

&lt;p&gt;I noticed that as my system prompt grew, the model started ignoring instructions in the middle. This is a known phenomenon called the "lost in the middle" effect. The more data you cram into the prompt to make it "smarter," the more you degrade its ability to follow specific logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving to RAG (Retrieval Augmented Generation)
&lt;/h2&gt;

&lt;p&gt;To fix this, I shifted to a RAG architecture. Instead of giving the model all the data upfront, I built a pipeline that retrieves only the relevant snippets of information based on the user's query.&lt;/p&gt;

&lt;p&gt;Here is the mental shift: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Database: Stores the facts.&lt;/li&gt;
&lt;li&gt;Retrieval Step: Finds the specific facts needed for the current question.&lt;/li&gt;
&lt;li&gt;LLM: Rewrites those facts into a human-sounding answer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By separating the knowledge from the reasoning, I solved two major problems. First, updating information became instant. I just update a document in the vector store, and the LLM sees the new version immediately. No need to re-engineer the prompt or wait for a fine-tuning run.&lt;/p&gt;

&lt;p&gt;Second, I gained auditability. When the bot gives an answer, I can log exactly which document snippet was retrieved. If the answer is wrong, I know if it is because the retrieval failed (wrong data) or the LLM failed (wrong reasoning).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Danger of Over-Prompting
&lt;/h2&gt;

&lt;p&gt;Many developers try to solve logic errors by adding more "rules" to the prompt. "Always do X, never do Y, remember to Z." This creates a fragile house of cards. Eventually, two rules will conflict, and the model will pick one at random.&lt;/p&gt;

&lt;p&gt;If you find your prompt is becoming a 200 line list of constraints, you probably need a state machine or a piece of traditional code. I replaced a complex "if-then" prompt chain with a simple Python switch statement that routed queries to different specialized prompts. The reliability jumped immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Takeaways
&lt;/h2&gt;

&lt;p&gt;If you are building AI features, follow these rules to keep your sanity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep your system prompts lean. Focus on the persona and the output format, not the raw data.&lt;/li&gt;
&lt;li&gt;Use a vector database for any information that changes more than once a month.&lt;/li&gt;
&lt;li&gt;If a task requires strict logic, write a function in your language of choice and let the LLM call that function instead of trying to "convince" the LLM to be logical.&lt;/li&gt;
&lt;li&gt;Log the retrieved context. You cannot debug an LLM if you do not know what data it was looking at when it hallucinated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stop trying to make the model remember everything. Let it be the brain, and give it a library to look things up in.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>database</category>
      <category>llm</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Stop Over-Engineering Your First Indie Project</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Tue, 07 Jul 2026 11:00:45 +0000</pubDate>
      <link>https://dev.to/ntty/stop-over-engineering-your-first-indie-project-ep1</link>
      <guid>https://dev.to/ntty/stop-over-engineering-your-first-indie-project-ep1</guid>
      <description>&lt;p&gt;I spent three weeks picking a database for a project that ended up getting four users. All of them were my cousins. &lt;/p&gt;

&lt;p&gt;As developers, we are trained to build for scale. We think about concurrency, latency, and maintainability from day one. But when you are building an indie project, your biggest risk is not a server crash. Your biggest risk is building something that nobody wants to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Infrastructure Trap
&lt;/h2&gt;

&lt;p&gt;It is easy to hide from the scary part of shipping by focusing on the technical stack. Spending five days configuring a Kubernetes cluster or debating between PostgreSQL and MongoDB feels like work. It feels productive because you are writing code and reading documentation.&lt;/p&gt;

&lt;p&gt;In reality, this is often a form of procrastination. You are optimizing for a problem you do not have. If your app gets 10,000 users in a day, you will have a great problem. Until then, the most scalable piece of software is the one that is actually live.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Boring Stack Advantage
&lt;/h2&gt;

&lt;p&gt;When I started shipping smaller projects, I switched to what I call the Boring Stack. This means using tools I already know inside and out, even if they are not the trendiest options on GitHub right now.&lt;/p&gt;

&lt;p&gt;If you know Rails, use Rails. If you know Laravel, use Laravel. If you know basic Node and Express, stick with that. &lt;/p&gt;

&lt;p&gt;Every hour you spend learning a new framework for a side project is an hour you are not spending on the actual product. The goal of an indie project is to validate an idea. You do not need a distributed system to validate if people want a specialized calorie tracker for dogs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Actually Focus
&lt;/h2&gt;

&lt;p&gt;Instead of worrying about the backend architecture, focus on these three areas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Core Loop: What is the one thing the user comes to do? Make that path as short as possible. If it takes ten clicks to reach the value, they will leave.&lt;/li&gt;
&lt;li&gt;Data Integrity: You do not need a complex NoSQL schema, but you do need to make sure you are not losing user data. Simple relational databases are almost always the right choice here.&lt;/li&gt;
&lt;li&gt;The Feedback Loop: Build a way to talk to your users. A simple email link or a basic contact form is more valuable than a perfectly tuned API.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Dealing with the Fear of Refactoring
&lt;/h2&gt;

&lt;p&gt;One common argument for over-engineering is the fear of technical debt. You tell yourself, "If I do it the right way now, I won't have to rewrite it later." &lt;/p&gt;

&lt;p&gt;Here is the truth: you probably will have to rewrite it. But you will rewrite it based on how users actually use the tool, not based on how you imagined they would use it. &lt;/p&gt;

&lt;p&gt;Writing "throwaway code" is a skill. Write the simplest version that works. If the project fails, you wasted very little time. If it succeeds, you now have the revenue or the user base to justify the time it takes to refactor the messy parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Concrete Takeaway
&lt;/h2&gt;

&lt;p&gt;Next time you start a project, set a strict limit on your setup phase. Give yourself 48 hours to pick your stack and deploy a "Hello World" to a live URL. If you spend more time than that on configuration before you have a single functional feature, you are over-engineering.&lt;/p&gt;

&lt;p&gt;Ship the ugly version. Fix the database later. The only metric that matters in the beginning is whether or not a stranger finds your tool useful.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>productivity</category>
      <category>sideprojects</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>SEO for Developers: Beyond Meta Tags</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Mon, 06 Jul 2026 11:00:31 +0000</pubDate>
      <link>https://dev.to/ntty/seo-for-developers-beyond-meta-tags-ni6</link>
      <guid>https://dev.to/ntty/seo-for-developers-beyond-meta-tags-ni6</guid>
      <description>&lt;p&gt;Most developers treat SEO as a checklist of meta tags that the marketing team asks for. We add a title, a description, and maybe some Open Graph tags, then we assume the job is done. But modern SEO is less about keywords and more about engineering performance and accessibility.&lt;/p&gt;

&lt;p&gt;If you want your site to rank, you need to stop thinking like a writer and start thinking like a browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Performance Trap
&lt;/h2&gt;

&lt;p&gt;Google uses Core Web Vitals as a ranking signal. This means your choice of framework and how you load assets directly affects your position in search results. The biggest culprit is usually Cumulative Layout Shift (CLS).&lt;/p&gt;

&lt;p&gt;CLS happens when elements jump around while the page is loading. This often occurs because images do not have defined dimensions or fonts swap after the initial render. To fix this, always set width and height attributes on images. If you are using a framework like Next.js or Nuxt, use their optimized image components to prevent layout shifts.&lt;/p&gt;

&lt;p&gt;Another common mistake is the massive JavaScript bundle. If your site relies entirely on client-side rendering (CSR), search engine bots have to execute your JS to see the content. While they are better at this than they used to be, it is slower and more prone to errors. Use Server-Side Rendering (SSR) or Static Site Generation (SSG) for any page that needs to be indexed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantic HTML is Not Optional
&lt;/h2&gt;

&lt;p&gt;Many of us have fallen into the div-soup trap. We use a div for everything and style it to look like a header or a button. However, search engines use semantic HTML to understand the hierarchy of your information.&lt;/p&gt;

&lt;p&gt;An h1 tag tells a bot what the page is about. An article tag defines a self-contained piece of content. A nav tag identifies the primary navigation. When you replace these with generic divs, you are stripping away the context that bots use to categorize your site.&lt;/p&gt;

&lt;p&gt;Here is a quick rule of thumb: if you can remove all the CSS and the page still makes logical sense to a screen reader, your SEO is in a good place. Accessibility and SEO are essentially the same goal: making content machine-readable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The URL Architecture
&lt;/h2&gt;

&lt;p&gt;Developers often create URLs that make sense for the database but not for a human or a bot. A URL like /product/12345 is useless for SEO. A URL like /product/mechanical-keyboard-blue-switches tells the bot exactly what is on the page before it even loads.&lt;/p&gt;

&lt;p&gt;If you are changing your URL structure, never just delete the old ones. This creates 404 errors that kill your ranking. Always implement 301 redirects. A 301 tells the search engine that the content has moved permanently, preserving the "link juice" from the old URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing the Crawl Budget
&lt;/h2&gt;

&lt;p&gt;Search engines do not spend infinite time on your site. They have a crawl budget. If you have thousands of duplicate pages or a messy internal linking structure, the bot might leave before it finds your most important content.&lt;/p&gt;

&lt;p&gt;Use a robots.txt file to tell bots which parts of your site to ignore. Do not let them crawl your admin panel, your search result pages, or your internal API endpoints. This forces the bot to spend its time on the pages that actually bring in users.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Concrete Takeaway
&lt;/h2&gt;

&lt;p&gt;Stop treating SEO as a post-production task. It should be part of your definition of done for any feature. &lt;/p&gt;

&lt;p&gt;Before you merge a PR, ask yourself these three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does this page shift visually while loading (CLS)?&lt;/li&gt;
&lt;li&gt;Am I using semantic HTML tags instead of just divs?&lt;/li&gt;
&lt;li&gt;Is the URL descriptive and does it redirect properly if it replaced an old one?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you focus on these technical foundations, the keyword optimization will actually work. You cannot optimize a site that is slow, inaccessible, or structurally broken.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>performance</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Building Chatbots: Moving Toward Agentic Content Workflows</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Sun, 05 Jul 2026 11:00:31 +0000</pubDate>
      <link>https://dev.to/ntty/stop-building-chatbots-moving-toward-agentic-content-workflows-48ie</link>
      <guid>https://dev.to/ntty/stop-building-chatbots-moving-toward-agentic-content-workflows-48ie</guid>
      <description>&lt;p&gt;Most developers start their AI journey by building a wrapper around a prompt. You send a request, you get a response, and you hope it is correct. This is a linear workflow. It works for simple tasks, but it falls apart when you try to produce high-quality technical documentation or SEO-driven content.&lt;/p&gt;

&lt;p&gt;When I first tried to automate our blog's technical deep-dives, I used a massive prompt. I told the LLM to "be an expert engineer, use a professional tone, and include code examples." The result was generic fluff. It looked like a marketing brochure because the LLM was trying to guess the right answer in one shot.&lt;/p&gt;

&lt;p&gt;To fix this, you need to move from a prompt to an agentic workflow. This means moving from a single call to a loop of planning, executing, and critiquing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Linear Prompts
&lt;/h2&gt;

&lt;p&gt;Linear prompts suffer from the "hallucination drift." If the model makes a mistake in the second paragraph, it will spend the rest of the article trying to justify that mistake to maintain internal consistency. It cannot go back and fix its own logic because it only moves forward.&lt;/p&gt;

&lt;p&gt;In a professional content operation, no human writer works this way. You do not write a 2,000 word technical guide in one sitting and hit publish. You outline, research, draft, review, and edit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing an Agentic Loop
&lt;/h2&gt;

&lt;p&gt;An agentic workflow breaks the task into specialized roles. Instead of one prompt, you build a pipeline of small, focused agents that talk to each other.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Researcher Agent
&lt;/h3&gt;

&lt;p&gt;This agent does not write. Its only job is to find facts. It should take a topic and produce a structured list of requirements, API references, and actual code snippets. If you are writing about a specific library, this agent should pull the latest documentation rather than relying on the LLM's training data.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Architect Agent
&lt;/h3&gt;

&lt;p&gt;This agent takes the research and builds a skeleton. It defines the H2s and H3s. It decides where the code blocks go. The goal here is structural integrity. If the outline is weak, the final article will be weak regardless of how good the prose is.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Writer Agent
&lt;/h3&gt;

&lt;p&gt;Now, the writer takes a single section of the outline at a time. By limiting the scope to one heading, you prevent the model from losing focus or skipping details to save tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The Critic Agent (The Most Important Part)
&lt;/h3&gt;

&lt;p&gt;This is where the magic happens. The Critic agent is prompted to be pedantic. It looks for: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generic adjectives (e.g., "powerful," "seamless").&lt;/li&gt;
&lt;li&gt;Lack of concrete examples.&lt;/li&gt;
&lt;li&gt;Logical gaps in the code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the Critic finds an issue, it sends the section back to the Writer with specific feedback. This loop continues until the Critic gives a thumbs up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing the Workflow
&lt;/h2&gt;

&lt;p&gt;You do not need complex frameworks to start this. A simple Python script with a few different system prompts and a while-loop can handle this logic. &lt;/p&gt;

&lt;p&gt;One technical tip: use a structured output format like JSON for the communication between agents. When the Researcher passes data to the Architect, it should be a JSON object with keys like &lt;code&gt;key_concepts&lt;/code&gt; and &lt;code&gt;source_urls&lt;/code&gt;. This prevents the Architect from getting confused by the Researcher's conversational filler.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway for Builders
&lt;/h2&gt;

&lt;p&gt;If you want to automate content that actually ranks and provides value, stop trying to find the "perfect prompt." It does not exist. Instead, build a system of checks and balances. &lt;/p&gt;

&lt;p&gt;Focus on the feedback loop. The quality of your output is not determined by the LLM you use, but by the rigor of your Critic agent.&lt;/p&gt;

&lt;p&gt;For those of us managing the research side of this, I have been using Citedy (&lt;a href="https://www.citedy.com" rel="noopener noreferrer"&gt;https://www.citedy.com&lt;/a&gt;) to keep sources organized and verifiable, which feeds directly into the Researcher agent's context window.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>automation</category>
      <category>llm</category>
    </item>
    <item>
      <title>Why Your Indie Project is Stuck in Development Hell</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Sat, 04 Jul 2026 11:00:32 +0000</pubDate>
      <link>https://dev.to/ntty/why-your-indie-project-is-stuck-in-development-hell-18l1</link>
      <guid>https://dev.to/ntty/why-your-indie-project-is-stuck-in-development-hell-18l1</guid>
      <description>&lt;p&gt;I have spent three years building a project that should have taken three months. &lt;/p&gt;

&lt;p&gt;For a long time, I told myself I was just ensuring quality. I was building a robust architecture. I was making sure the edge cases were handled. In reality, I was terrified of launching. I was hiding behind my IDE because as long as the project is 'in development', it cannot fail. Once you ship it, the world gets to tell you if your idea is actually useful.&lt;/p&gt;

&lt;p&gt;If you are an indie developer and your project has been at 90 percent completion for six months, you are probably trapped in the same loop. Here is how to break it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trap of the Perfect Stack
&lt;/h2&gt;

&lt;p&gt;When we build for a company, we have a manager or a product owner telling us what the priority is. When we build for ourselves, we often prioritize the tech we want to learn over the product the user needs. &lt;/p&gt;

&lt;p&gt;I once spent two weeks migrating a small internal tool from a simple REST API to GraphQL because I wanted to get comfortable with the ecosystem. The tool had zero users. I spent forty hours optimizing a query for a database that held ten rows of data. &lt;/p&gt;

&lt;p&gt;Stop treating your indie project like a portfolio piece for a FAANG interview. Your users do not care if you used a microservices architecture or if your Redux store is perfectly normalized. They care if the button works and the problem gets solved.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Feature Creep Spiral
&lt;/h2&gt;

&lt;p&gt;Feature creep usually starts with a thought like, "It would be cool if it also did X." &lt;/p&gt;

&lt;p&gt;Then you realize that to do X, you need to change your data model. Then you realize you need a new authentication flow to support X. Suddenly, you are three weeks deep into a feature that was not part of your original value proposition.&lt;/p&gt;

&lt;p&gt;Every new feature adds a tax. Not just the time to build it, but the time to test it and the cognitive load of maintaining it. If you keep adding features before your first user signs up, you are just guessing what people want. You are building a solution for a problem that might not exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 'Just One More Tweak' Fallacy
&lt;/h2&gt;

&lt;p&gt;There is a specific kind of anxiety that hits right before you hit deploy. You find a weird CSS bug on a screen size that only three people in the world use. You decide you cannot possibly launch with that bug. &lt;/p&gt;

&lt;p&gt;This is a procrastination tactic. Your brain is trying to protect you from the vulnerability of being judged. &lt;/p&gt;

&lt;p&gt;Accept that your first version will be ugly. It will have bugs. The UI will be slightly off in some browsers. That is fine. The goal of a V1 is not to be perfect. The goal is to validate that someone actually wants what you are building.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Actually Ship
&lt;/h2&gt;

&lt;p&gt;If you are stuck, try these three rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The Hard Cutoff: Pick a date. Not a window, but a date. If the project is not live by that Friday at 5 PM, you have failed. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Feature Freeze: List every feature you think you need. Now, delete half of them. Then, delete half of what is left. Whatever remains is your MVP. Everything else goes into a 'Future' text file that you are not allowed to open until you have ten active users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The 'Good Enough' Threshold: If a feature works and does not crash the app, it is done. Do not spend another hour on it. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;Shipping is a skill, just like coding. If you never ship, you never learn how to handle feedback, how to debug in production, or how to market a product. &lt;/p&gt;

&lt;p&gt;Stop polishing the chrome on a car that does not have an engine. Get it on the road, let it rattle and shake, and fix the parts that actually break based on real world usage. The most successful indie projects are rarely the ones with the cleanest code. They are the ones that solved a real problem and got into the hands of users the fastest.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
      <category>sideprojects</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Stop Building Chatbots: Start Building Agentic Content Pipelines</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Fri, 03 Jul 2026 13:57:47 +0000</pubDate>
      <link>https://dev.to/ntty/stop-building-chatbots-start-building-agentic-content-pipelines-1eph</link>
      <guid>https://dev.to/ntty/stop-building-chatbots-start-building-agentic-content-pipelines-1eph</guid>
      <description>&lt;h2&gt;
  
  
  The Chatbot Trap
&lt;/h2&gt;

&lt;p&gt;Most developers start with a chat interface. You build a wrapper around an LLM, add some system prompts, and call it an AI tool. But if you are building for content operations or SEO, a chat interface is actually a bottleneck. It requires a human to sit there, prompt the AI, check the result, and prompt it again.&lt;/p&gt;

&lt;p&gt;That is not an agent. That is just a fancy text editor.&lt;/p&gt;

&lt;p&gt;Agentic workflows are different. An agent does not wait for you to tell it what to do next. It has a goal, a set of tools, and a loop that allows it to self-correct. Instead of "Write a blog post about React," an agentic pipeline looks like: "Research the current state of React Server Components, find three conflicting opinions, draft a technical comparison, and verify the code snippets against the latest docs."&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture of a Content Agent
&lt;/h2&gt;

&lt;p&gt;To move from a prompt to a pipeline, you need three specific components: a Planner, an Executor, and a Critic.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Planner
&lt;/h3&gt;

&lt;p&gt;The planner breaks the high-level goal into a graph of tasks. If you want to create a technical guide, the planner should not just start writing. It should create a checklist: search for documentation, identify common pitfalls, outline the structure, and draft the sections.&lt;/p&gt;

&lt;p&gt;I recommend using a state machine for this. If you use a tool like LangGraph or a simple custom loop, you can track which stage the content is in. If the 'Research' stage fails to find a source, the planner should loop back and try a different search query rather than just hallucinating a fact.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Executor (The Tool Belt)
&lt;/h3&gt;

&lt;p&gt;An LLM alone is a closed system. To make it agentic, you must give it tools. For content ops, this usually means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A search API (Tavily or Serper) to get real-time data.&lt;/li&gt;
&lt;li&gt;A scraper to parse technical documentation.&lt;/li&gt;
&lt;li&gt;A code execution environment to test the snippets it generates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the executor hits a wall, it should be able to emit a signal. For example, if a documentation page is behind a login or uses a weird JS framework, the executor should report this back to the planner to find an alternative source.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Critic (The Quality Gate)
&lt;/h3&gt;

&lt;p&gt;This is where most builders fail. They trust the first output. A true agentic workflow uses a separate LLM call (or a different model entirely) to act as the editor. &lt;/p&gt;

&lt;p&gt;The Critic should have a specific rubric: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are there any generic phrases?&lt;/li&gt;
&lt;li&gt;Does the code actually run?&lt;/li&gt;
&lt;li&gt;Is the claim backed by a source?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the Critic finds an issue, it sends the draft back to the Executor with specific instructions on what to fix. This loop continues until the Critic gives a "thumbs up."&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling the 'GEO' Problem
&lt;/h2&gt;

&lt;p&gt;Generative Engine Optimization (GEO) is the new SEO. When AI search engines like Perplexity or SearchGPT summarize a topic, they don't just look for keywords. They look for citations, authoritative data, and clear structures.&lt;/p&gt;

&lt;p&gt;If your agentic pipeline just scrapes the web and rewrites it, you are creating noise. To win at GEO, your agent needs to synthesize. It should look for gaps in existing content and fill them. Instead of summarizing five articles, the agent should identify where those five articles disagree and explain why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Implementation Tips
&lt;/h2&gt;

&lt;p&gt;If you are building this today, keep these lessons in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid long prompts. Break your system prompt into smaller, task-specific prompts for the Planner, Executor, and Critic.&lt;/li&gt;
&lt;li&gt;Use structured output. Force your agent to return JSON. It is the only way to reliably pass data between different stages of the pipeline.&lt;/li&gt;
&lt;li&gt;Log everything. When an agent loops infinitely or goes off the rails, you need to see exactly which tool call caused the drift.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;Stop thinking about AI as a conversation. Think of it as a series of micro-services. The goal is to build a system where the human is the editor-in-chief, not the prompt engineer. When you shift from "Chat" to "Pipeline," you move from generating a few pages of text to running a scalable content operation.&lt;/p&gt;

&lt;p&gt;For those of us dealing with the research and citation side of this, I have been using Citedy (&lt;a href="https://www.citedy.com" rel="noopener noreferrer"&gt;https://www.citedy.com&lt;/a&gt;) to help manage sources and ensure accuracy in the final output.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>automation</category>
      <category>llm</category>
    </item>
    <item>
      <title>Agent-ready short links from the command line</title>
      <dc:creator>Ntty</dc:creator>
      <pubDate>Fri, 12 Jun 2026 19:57:06 +0000</pubDate>
      <link>https://dev.to/ntty/agent-ready-short-links-from-the-command-line-5bfn</link>
      <guid>https://dev.to/ntty/agent-ready-short-links-from-the-command-line-5bfn</guid>
      <description>&lt;p&gt;Most short-link tools are designed around a dashboard. I did it for agents.&lt;/p&gt;

&lt;p&gt;That works when a marketer is setting up campaigns manually. It is awkward when the workflow starts in a terminal, CI job, documentation script, launch checklist, or coding agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lnkgo&lt;/strong&gt; is a small API/CLI-first link service for branded tracked links.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;npm CLI: &lt;strong&gt;npm install -g lnkgo&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;agent skill: &lt;strong&gt;npx --yes skills add citedy/lnkgo --skill lnkgo&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can create a short link, generate a QR code, read analytics, and verify a custom domain without opening a dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example agent use cases
&lt;/h2&gt;

&lt;p&gt;Create a campaign link:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a Lnkgo link for this launch URL and tag it producthunt.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Track a partner page:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a partner link, then summarize clicks by referrer tomorrow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Generate a QR:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a tracked link and save a QR code as event-qr.png.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use a custom domain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Check my domain status, then create the link on links.example.com.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Summarize analytics:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fetch analytics for this link id and give me totals, countries, and top referrers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  CLI example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lnkgo create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://example.com/launch &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tag&lt;/span&gt; devto &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tag&lt;/span&gt; launch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use the returned &lt;code&gt;id&lt;/code&gt; for QR and analytics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lnkgo qr &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LINK_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; event-qr.png
lnkgo analytics &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LINK_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  REST API example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.lnkgo.app/v1/links"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$LNKGO_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Idempotency-Key: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;uuidgen | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'[:upper:]'&lt;/span&gt; &lt;span class="s1"&gt;'[:lower:]'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"url":"https://example.com/launch","tags":["producthunt","launch"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Custom domains
&lt;/h2&gt;

&lt;p&gt;Default links use &lt;code&gt;lnkgo.app&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want your own domain, request it, add the returned DNS proof records, and create links on that domain after it becomes active.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launch limits
&lt;/h2&gt;

&lt;p&gt;Email verification starts with safe starter limits. Domain ownership proof unlocks the launch offer: up to 10 custom domains, 10,000 links/month, 1,000 links/domain/month, 50,000 API calls/month, and 14-day analytics.&lt;/p&gt;

&lt;p&gt;Try it here:&lt;br&gt;
&lt;a href="https://lnkgo.app" rel="noopener noreferrer"&gt;https://lnkgo.app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>api</category>
    </item>
  </channel>
</rss>
