<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>AI Programming on Interesting AI</title>
    <link>http://www.wfcoding.com/en/tags/ai-programming/</link>
    <description>Recent content in AI Programming on Interesting AI</description>
    <generator>Hugo -- 0.164.0</generator>
    <language>en-US</language>
    <copyright>火云</copyright>
    <lastBuildDate>Mon, 17 Aug 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="http://www.wfcoding.com/en/tags/ai-programming/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>[Collection] Architectural Foundations: The Underlying Methodology for Mastering AI-Assisted Programming</title>
      <link>http://www.wfcoding.com/en/articles/design/01.%E6%9E%B6%E6%9E%84%E7%AD%91%E5%9F%BA/</link>
      <pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/01.%E6%9E%B6%E6%9E%84%E7%AD%91%E5%9F%BA/</guid>
      <description>&lt;p&gt;&lt;strong&gt;AI handles the &amp;ldquo;speed,&amp;rdquo; humans handle the &amp;ldquo;blueprints.&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
This column outlines common software architecture design techniques, aiming to teach you how to tame AI to write industrial-grade, highly maintainable, high-quality code through &amp;ldquo;architectural design&amp;rdquo; and &amp;ldquo;rule constraints (Prompt / Rules),&amp;rdquo; avoiding the pitfall of &amp;ldquo;the more code you write, the faster the system crashes.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Architect &#43; AI: The Career Leap from Coder to System Orchestrator</title>
      <link>http://www.wfcoding.com/en/articles/design/0118/</link>
      <pubDate>Mon, 17 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0118/</guid>
      <description>&lt;p&gt;In this series, we have discussed a range of engineering practices: frontend-backend separation, DDD (Domain-Driven Design), layered architecture, DI (Dependency Injection), RESTful (Representational State Transfer), async &amp;amp; concurrency, SSE (Server-Sent Events), plugin architecture, and Project Rules.&lt;/p&gt;
&lt;p&gt;It may look like a lot of technology, but they all ultimately point to the same question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Now that AI can generate large amounts of code, what is still the most important capability for a programmer?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The answer is shifting from:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;How to write the code&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;to:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;How to design a system in which AI can write code correctly.&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Plugin Architecture and Extension Points: Guiding AI Toward Modular, Pluggable Development for Decoupled, Iterable Features</title>
      <link>http://www.wfcoding.com/en/articles/design/0117/</link>
      <pubDate>Mon, 17 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0117/</guid>
      <description>&lt;p&gt;AI writes code fast, but it is also prone to a typical problem:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Every time a feature is added, more &lt;code&gt;if/elif&lt;/code&gt; branches pile into the core code.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;domain&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;legal&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;domain&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;finance&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;domain&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;medical&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With few features this is fine, but as the types keep growing, the core module becomes increasingly bloated, and every new feature risks affecting existing logic.&lt;/p&gt;
&lt;p&gt;A more reasonable approach is to define upfront:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Plugin&lt;/strong&gt;
&lt;strong&gt;Extension Point&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And let AI follow one principle:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;New capabilities should preferably be added as new modules, not by modifying the core flow.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Long-Lived Connections and Streaming Push: Standardizing SSE / WebSocket Implementations to Replace Inefficient Polling</title>
      <link>http://www.wfcoding.com/en/articles/design/0116/</link>
      <pubDate>Sun, 16 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0116/</guid>
      <description>&lt;p&gt;In web systems, there is a type of requirement that is especially prone to being implemented by AI as &amp;ldquo;it runs, but it&amp;rsquo;s dumb&amp;rdquo;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Frontend:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Ask the server every 1 second
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;Is the task done?&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Server:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;No.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Ask again 1 second later:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;Is it done?&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This approach is called:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Polling&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Querying a status occasionally is fine, but for real-time scenarios such as AI streaming responses, OCR progress, document parsing, knowledge base construction, and background task status, high-frequency polling generates a large number of useless requests.&lt;/p&gt;
&lt;p&gt;A more appropriate solution is usually:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;SSE (Server-Sent Events)&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WebSocket — a full-duplex, long-lived connection protocol&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The core idea boils down to one sentence:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don&amp;rsquo;t make the client keep asking &amp;ldquo;Got any message yet?&amp;rdquo; — let the server push messages proactively when there is something new.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Async and Concurrency Architecture: Fixing AI&#39;s Synchronous Blocking Patterns to Improve System Throughput</title>
      <link>http://www.wfcoding.com/en/articles/design/0115/</link>
      <pubDate>Sat, 15 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0115/</guid>
      <description>&lt;p&gt;There is a very common problem with AI-generated code:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The code runs, but slows down as soon as multiple users access it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Especially in Python Web projects, even when using FastAPI and functions are written as &lt;code&gt;async def&lt;/code&gt;, operations such as database queries, HTTP requests, and large language model (LLM) calls may still block synchronously.&lt;/p&gt;
&lt;p&gt;The key issue is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;async def&lt;/code&gt; is merely the entry point of an asynchronous function — it does not automatically turn the synchronous code inside it into asynchronous code.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For systems that heavily rely on external I/O — such as web services, knowledge bases, and agent platforms — establishing a unified async and concurrency architecture is an important foundation for improving system throughput.&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Centralized Configuration and I18n: Strictly Forbid AI Magic Values and Hardcoded Parameters</title>
      <link>http://www.wfcoding.com/en/articles/design/0114/</link>
      <pubDate>Fri, 14 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0114/</guid>
      <description>&lt;p&gt;AI (Artificial Intelligence) has a very common problem when writing code:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It loves to &amp;ldquo;hardcode things on a whim.&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;timeout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;max_retries&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;qwen3:14b&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ValueError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;User does not exist&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Individually, there&amp;rsquo;s nothing fundamentally wrong with any of these lines.&lt;/p&gt;
&lt;p&gt;But when dozens of modules each have their own &lt;code&gt;30&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, model names, and prompt text, maintainers start getting headaches:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What do these values mean? Where should they be changed? What happens when switching environments? How do we support English?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Therefore, AI programming projects should establish a clear architectural rule upfront:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Values with business significance, environment-specific differences, or user-visible meaning are not allowed to be scattered across business code.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This problem is primarily addressed through two mechanisms:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Centralized Configuration + I18n (Internationalization).&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Caching and Multi-Level Storage: Don&#39;t Let AI Blindly Hit the Database</title>
      <link>http://www.wfcoding.com/en/articles/design/0112/</link>
      <pubDate>Wed, 12 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0112/</guid>
      <description>&lt;p&gt;When AI writes business code, it has a very typical tendency:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user_db&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_by_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Functionally correct. But if every read in the project becomes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Read user → Database
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Read permissions → Database
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Read model → Database
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Read Agent → Database
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Read knowledge base → Database
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Read config → Database
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The system soon enters a state where:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Every function is correct, yet the overall architecture grows increasingly inefficient.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The problem is not merely &amp;ldquo;whether there is a cache&amp;rdquo;, but:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The AI never first asks: what I want to reuse — a &amp;ldquo;value&amp;rdquo;, or an &amp;ldquo;already-built runtime object&amp;rdquo;?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is exactly what&amp;rsquo;s most worth borrowing from &lt;a href=&#34;https://github.com/liupras/miniagent&#34;&gt;miniagent&lt;/a&gt;&amp;rsquo;s current caching architecture.&lt;/p&gt;
&lt;p&gt;It doesn&amp;rsquo;t just build one cache — it explicitly splits into two categories:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Object Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Object caching
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Value Cache
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Value caching
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These two solve fundamentally different problems.&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Unified Authentication and Authorization: Standardizing AI Token Issuance and Verification Logic</title>
      <link>http://www.wfcoding.com/en/articles/design/0111/</link>
      <pubDate>Tue, 11 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0111/</guid>
      <description>&lt;p&gt;In AI programming, there is one category of code that easily &amp;ldquo;grows and grows messier&amp;rdquo;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;role&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HTTPException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;403&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Switch to another endpoint, and the AI writes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;user:delete&amp;#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;permissions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ForbiddenError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Yet another endpoint:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_user&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;owner_id&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_user&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_admin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HTTPException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;403&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each snippet looks defensible on its own. But once dozens of variations of these &lt;code&gt;if&lt;/code&gt;s appear across the project, the permission system has effectively gone out of control.&lt;/p&gt;
&lt;p&gt;The mature solution is not &amp;ldquo;make the AI write its if-statements more carefully&amp;rdquo;, but to establish a unified:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Authentication + permission model + permission enforcement mechanism&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The most common permission model here is &lt;strong&gt;RBAC (Role-Based Access Control)&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Aspect-Oriented Programming: Guiding AI to Extract Cross-Cutting Logic So Logging, Auth, and Instrumentation Are Never Written Twice</title>
      <link>http://www.wfcoding.com/en/articles/design/0110/</link>
      <pubDate>Mon, 10 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0110/</guid>
      <description>&lt;p&gt;In the age of AI programming, there is one kind of code that gets copied around with abandon:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Start processing request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UnauthorizedError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;do_something&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Execution time: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At first there is only one endpoint, and it looks harmless enough.&lt;/p&gt;
&lt;p&gt;But once the project grows to dozens or even hundreds of endpoints, things quickly become:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;User endpoints
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Authentication
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Logging
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Parameter validation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Business logic
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  └─ Instrumentation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Agent endpoints
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Authentication
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Logging
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Parameter validation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Business logic
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  └─ Instrumentation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Knowledge base endpoints
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Authentication
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Logging
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Parameter validation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ├─ Business logic
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  └─ Instrumentation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The only truly different part is the few lines of business logic in the middle. As for the rest, every time the AI writes another endpoint, it dutifully copies it all over again.&lt;/p&gt;
&lt;p&gt;This is exactly the problem that &lt;strong&gt;AOP (Aspect-Oriented Programming)&lt;/strong&gt; set out to solve.&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>RESTful and Contract First: Standardizing Interface Definitions and Unifying API Design Paradigms</title>
      <link>http://www.wfcoding.com/en/articles/design/0109/</link>
      <pubDate>Sun, 09 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0109/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Define the API rules clearly first, then let AI write the code.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In AI-assisted development, interface design is an area that easily &amp;ldquo;looks like it works, but gets increasingly messy over time.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Ask AI to write a few APIs for you, and it might quickly generate:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/getUser
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/createUser
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/update_user
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/delete-user
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/userList
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;They all work functionally. But as the project continues to grow, you easily end up with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Same resource, different naming
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Same action, different HTTP methods
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Same error, different response structures
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Same pagination, different field names
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Eventually, frontend developers, backend developers, testers, and even AI itself start guessing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;How exactly should this API be called?&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What&amp;rsquo;s truly missing here is not coding ability, but:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A unified API contract.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Logging Architecture: Making Every Log Line AI Writes Valuable</title>
      <link>http://www.wfcoding.com/en/articles/design/0108/</link>
      <pubDate>Sat, 08 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0108/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Standardize log formats, log levels, and trace instrumentation so that AI stops logging chaotically everywhere.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As AI-assisted programming becomes increasingly common, an easily overlooked problem is emerging:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI is very good at writing logs, but not necessarily good at writing &amp;ldquo;useful logs.&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ask AI to implement a feature, and it will likely generate something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;start&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;processing...&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;data loaded&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;failed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Individually, these seem fine. But as the project grows larger, you&amp;rsquo;ll find your logs turning into something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;start
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;processing...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;loading data...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;done
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;request failed
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;retry...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;success
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When something actually breaks, it becomes very difficult to answer a few of the most basic questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which request caused the error?&lt;/li&gt;
&lt;li&gt;Which module caused the error?&lt;/li&gt;
&lt;li&gt;Which step caused the error?&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The problem is rarely &amp;ldquo;too few logs.&amp;rdquo; It&amp;rsquo;s usually:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;There are plenty of logs, but no system behind them.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Therefore, just like exception handling, dependency injection, and interface contracts, &lt;strong&gt;logging should also be part of the project architecture — not left to the free rein of developers or AI.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Dependency Injection: Forbid AI from Hardcoding Instantiation, Improve Testability and Extensibility</title>
      <link>http://www.wfcoding.com/en/articles/design/0107/</link>
      <pubDate>Fri, 07 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0107/</guid>
      <description>&lt;p&gt;When AI writes code, it loves the &amp;ldquo;fastest way to make it run&amp;rdquo; approach, for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Database&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RedisCache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;mailer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EmailService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;service&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UserService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create wherever needed.&lt;/p&gt;
&lt;p&gt;In the short term it&amp;rsquo;s convenient, but as the project grows larger, you end up with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Database instances created everywhere
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Cache clients created everywhere
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Configuration scattered
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Services instantiating each other
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Dependencies impossible to replace during testing
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The most obvious problem with this kind of code is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Objects hardcode their own dependencies.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And &lt;strong&gt;DI (Dependency Injection)&lt;/strong&gt; is exactly what solves this problem.&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Exception and Unified Encapsulation Architecture: Standardizing Unified Return Values, Global Exception Handling, and Parameter Validation</title>
      <link>http://www.wfcoding.com/en/articles/design/0106/</link>
      <pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0106/</guid>
      <description>&lt;p&gt;AI is very good at quickly writing API endpoints. For example, if you tell it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Add an endpoint to create a user.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It can probably produce working code in a few minutes. But without unified standards in the project, different endpoints will quickly end up like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;success&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Another endpoint returns:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;code&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ok&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When yet another endpoint encounters an error, it directly returns:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;user not found&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Some places even throw raw database exceptions back to the frontend.&lt;/p&gt;
&lt;p&gt;Every single endpoint &amp;ldquo;works,&amp;rdquo; but the entire system becomes increasingly hard to maintain.&lt;/p&gt;
&lt;p&gt;So, there&amp;rsquo;s a very important but often overlooked category of foundational architecture in AI programming:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Unified response values + global exception handling + unified parameter validation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Their purpose is to define upfront:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How to return on success, how to return on failure, and where to intercept invalid input.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Layered Clean Architecture: Standardizing Project Directory Structure to Prevent AI Boundary Violations</title>
      <link>http://www.wfcoding.com/en/articles/design/0105/</link>
      <pubDate>Wed, 05 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0105/</guid>
      <description>&lt;p&gt;AI writing code has one very common problem:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;It knows how a feature should be implemented, but doesn&amp;rsquo;t necessarily know where the code should go.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For example, if you tell AI:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Add a delete Agent feature.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Without a clear project structure, it might directly, inside the API endpoint: &lt;code&gt;query the database&lt;/code&gt;, &lt;code&gt;evaluate business rules&lt;/code&gt;, &lt;code&gt;clear the cache&lt;/code&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;The feature might work quickly. But as AI writes code this way again and again, the project will eventually become:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Business logic inside the API
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Database operations inside Services
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Business judgments inside Repositories
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Utility classes referenced everywhere
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point, we need another very fundamental yet extremely important architectural concept:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Layering.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Domain-Driven Design: Drawing Context Boundaries for AI to Say Goodbye to &#34;Big Ball of Mud&#34; Code</title>
      <link>http://www.wfcoding.com/en/articles/design/0104/</link>
      <pubDate>Tue, 04 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0104/</guid>
      <description>&lt;p&gt;Getting AI to write a single feature is usually not difficult. What&amp;rsquo;s truly difficult is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;After AI writes dozens or even hundreds of features in a row, can the code still remain clear?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Many projects start with a decent structure — a bit of user functionality here, some permission handling there, order features over there, logging features somewhere else.&lt;/p&gt;
&lt;p&gt;As requirements grow, different modules start calling each other, referencing each other, modifying each other, and may eventually end up like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;user.py
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;permission.py
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;agent.py
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tool.py
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;knowledge_base.py
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;conversation.py
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ↘
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  calls user.py again
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are plenty of files and lots of code, but who is responsible for what becomes increasingly unclear.&lt;/p&gt;
&lt;p&gt;Software architecture has a very vivid name for this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Big Ball of Mud&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And Domain-Driven Design, or &lt;strong&gt;DDD&lt;/strong&gt; as we often hear, has one very important role: drawing boundaries clearly before the system starts to get messy.&lt;/p&gt;
&lt;p&gt;For AI programming, this role is especially critical.&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>Frontend-Backend Separation: Constraining AI&#39;s Division of Labor to Avoid Interface Coupling and Responsibility Confusion</title>
      <link>http://www.wfcoding.com/en/articles/design/0103/</link>
      <pubDate>Mon, 03 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0103/</guid>
      <description>&lt;p&gt;AI is very good at writing code. But without clear architectural boundaries, it can easily develop one problem:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Wherever it&amp;rsquo;s convenient to write code, that&amp;rsquo;s where the code gets written.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Business rules that should belong to the backend might end up stuffed into Vue pages. API calls that should be uniformly encapsulated might scatter across various components. The frontend might even &amp;ldquo;invent&amp;rdquo; its own data structures inconsistent with the backend, based on page requirements.&lt;/p&gt;
&lt;p&gt;The code might run, but the project gradually loses its boundaries.&lt;/p&gt;
&lt;p&gt;And &lt;strong&gt;frontend-backend separation&lt;/strong&gt; is the first important boundary to draw for AI.&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>How to Define Coding Boundaries for AI Using Project Rules</title>
      <link>http://www.wfcoding.com/en/articles/design/0102/</link>
      <pubDate>Sun, 02 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0102/</guid>
      <description>&lt;p&gt;In the previous article, we discussed a core principle:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Define boundaries and rules first, then let AI exercise its capabilities within those boundaries.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So here comes the question:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How can these architecture rules actually be handed over to AI?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The answer is the topic of this article — &lt;strong&gt;Project Rules&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;</description>
    </item>
    <item>
      <title>The More You Rely on AI to Write Code, the Less You Can Afford to Skip Architecture Design</title>
      <link>http://www.wfcoding.com/en/articles/design/0101/</link>
      <pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate>
      <guid>http://www.wfcoding.com/en/articles/design/0101/</guid>
      <description>&lt;p&gt;With the development of large language models such as GPT, Claude, Gemini, and Qwen, software development is entering a new era.
Coding tasks that once took hours or even days can now be completed by AI in a matter of minutes.
However, many teams have noticed a puzzling phenomenon:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The more code gets written, the faster the project falls apart.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The reason is not that AI isn&amp;rsquo;t smart enough, but rather:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A lack of architectural constraints.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One important reason modern AI Agents can operate relatively stably is that: &lt;strong&gt;they do not let large language models run wild without any constraints.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Mature Agent systems typically define clear behavioral boundaries for the model through mechanisms such as System Instructions (i.e., system prompts), Tool Specifications (i.e., tool specs), permission control, workflows, state management, and result validation.&lt;/p&gt;
&lt;p&gt;In essence, this is highly consistent with the philosophy of software architecture:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Define the boundaries and rules first, then let AI exercise its capabilities within those boundaries.&lt;/strong&gt;
Even a highly capable model, when lacking clear constraints, dealing with ever-expanding context, or wielding excessive tool permissions, may gradually develop issues such as &lt;strong&gt;format drift, responsibility overreach, incorrect tool invocations, or inconsistent code style&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;</description>
    </item>
  </channel>
</rss>
