<?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: Daichi</title>
    <description>The latest articles on DEV Community by Daichi (@daichi_4de7a4be20102).</description>
    <link>https://dev.to/daichi_4de7a4be20102</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3811303%2F23928cb1-a057-4cfc-8013-9885ff9385a2.png</url>
      <title>DEV Community: Daichi</title>
      <link>https://dev.to/daichi_4de7a4be20102</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/daichi_4de7a4be20102"/>
    <language>en</language>
    <item>
      <title>Building a RAG-Based Subsidy Matching System from Scratch with Python</title>
      <dc:creator>Daichi</dc:creator>
      <pubDate>Sat, 28 Mar 2026 10:50:41 +0000</pubDate>
      <link>https://dev.to/daichi_4de7a4be20102/building-a-rag-based-subsidy-matching-system-from-scratch-with-python-22a9</link>
      <guid>https://dev.to/daichi_4de7a4be20102/building-a-rag-based-subsidy-matching-system-from-scratch-with-python-22a9</guid>
      <description>&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;A RAG (Retrieval-Augmented Generation) system that helps Japanese small businesses find government subsidies. Users describe their business situation, and the system retrieves relevant subsidies from a vector database, then generates a detailed answer using Claude API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why RAG Instead of Just Using an LLM?
&lt;/h2&gt;

&lt;p&gt;LLMs alone have three problems for this use case:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hallucination&lt;/strong&gt; — They confidently make up subsidy details that don't exist&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stale data&lt;/strong&gt; — Subsidy information updates frequently; LLM training data can't keep up&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No sources&lt;/strong&gt; — Users need to verify the information, but LLMs don't cite where it came from&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;RAG solves all three by &lt;strong&gt;retrieving real data first&lt;/strong&gt;, then passing it to the LLM as context. The LLM generates answers grounded in actual documents, not its training data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Query
    │
    ▼
┌─────────────┐     ┌──────────────┐
│  Retriever  │────▶│  Generator   │
│ (embed +    │     │ (Claude API) │
│  search)    │     └──────┬───────┘
└──────┬──────┘            │
       │                   ▼
┌──────▼──────┐      AI Answer
│  ChromaDB   │      with sources
│ (Vector DB) │
└─────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The data ingestion pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JSON Data → Sentence Chunker → Embedding Model → ChromaDB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tech Stack and Why
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Embedding&lt;/td&gt;
&lt;td&gt;multilingual-e5-large&lt;/td&gt;
&lt;td&gt;Best multilingual performance for free. Runs locally — no data leaves the machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vector DB&lt;/td&gt;
&lt;td&gt;ChromaDB&lt;/td&gt;
&lt;td&gt;Zero config. &lt;code&gt;pip install&lt;/code&gt; and it works with local persistence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM&lt;/td&gt;
&lt;td&gt;Claude API&lt;/td&gt;
&lt;td&gt;Strong long-context handling and Japanese language quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Streamlit&lt;/td&gt;
&lt;td&gt;Full UI in ~40 lines of Python&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Why Not LangChain/LlamaIndex?
&lt;/h3&gt;

&lt;p&gt;I intentionally built the pipeline from scratch first. Frameworks abstract away the internals, which is great for production but bad for learning. By writing each step manually — chunking, embedding, storing, retrieving, prompting — I understood exactly what each piece does and why it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Implementation Details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Sentence-Boundary Chunking
&lt;/h3&gt;

&lt;p&gt;The most impactful decision was &lt;strong&gt;how to split documents into chunks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Naive approach&lt;/strong&gt; (fixed-size split):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...eligible IT tools include accounting software, ord  ← cut mid-sentence
er management software, payment software...           ← next chunk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;My approach&lt;/strong&gt; (split at Japanese sentence boundaries &lt;code&gt;。&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sentences&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;。&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Greedily pack sentences into chunks up to CHUNK_SIZE
# Overlap the tail for context continuity
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This preserves semantic meaning in each chunk, which directly improves retrieval accuracy.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Embedding with Prefix
&lt;/h3&gt;

&lt;p&gt;multilingual-e5 requires specific prefixes to distinguish between stored passages and search queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# When indexing documents
&lt;/span&gt;&lt;span class="n"&gt;prefixed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passage: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# When searching
&lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Missing this prefix is a common mistake that silently degrades search quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Prompt Design for Grounded Answers
&lt;/h3&gt;

&lt;p&gt;The generation prompt explicitly constrains the LLM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;You are a Japanese subsidy advisor.
Answer based on the reference information below.
If information is insufficient, state that explicitly.
For critical details like deadlines and amounts, be precise.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reduces hallucination by telling the model to stick to the provided context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluation: Measuring What Matters
&lt;/h2&gt;

&lt;p&gt;Building a RAG that "seems to work" isn't enough. I created a test suite with 10 queries, each with an expected correct subsidy:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Query&lt;/th&gt;
&lt;th&gt;Expected Result&lt;/th&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Want to introduce accounting software"&lt;/td&gt;
&lt;td&gt;Digital/AI Subsidy&lt;/td&gt;
&lt;td&gt;1st&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Want to install new manufacturing equipment"&lt;/td&gt;
&lt;td&gt;Manufacturing Subsidy&lt;/td&gt;
&lt;td&gt;2nd&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Small shop wanting to attract customers via flyers"&lt;/td&gt;
&lt;td&gt;Small Business Sustainability Subsidy&lt;/td&gt;
&lt;td&gt;1st&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Restaurant wanting to start EC business"&lt;/td&gt;
&lt;td&gt;New Business Advancement Subsidy&lt;/td&gt;
&lt;td&gt;3rd&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Want to convert part-timers to full-time"&lt;/td&gt;
&lt;td&gt;Career Up Grant&lt;/td&gt;
&lt;td&gt;1st&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Results:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hit Rate @5&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;100%&lt;/strong&gt; (10/10)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MRR @5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.817&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hit Rate @5&lt;/strong&gt;: The correct answer appeared in the top 5 results for every query&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MRR (Mean Reciprocal Rank)&lt;/strong&gt;: On average, the correct answer ranked between 1st and 2nd place&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why These Metrics?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hit Rate&lt;/strong&gt; tells you "can the system find the right answer at all?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MRR&lt;/strong&gt; tells you "how quickly does it find it?" (1st place = 1.0, 2nd = 0.5, 3rd = 0.33)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are standard IR (Information Retrieval) metrics. Having these numbers lets you objectively compare different chunking strategies, embedding models, or retrieval parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Chunking strategy matters more than the embedding model
&lt;/h3&gt;

&lt;p&gt;Switching from fixed-size to sentence-boundary chunking had a bigger impact on retrieval quality than I expected. The embedding model can only work with what it's given — if chunks are semantically broken, even the best model can't fix that.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Evaluation should come before optimization
&lt;/h3&gt;

&lt;p&gt;Building the evaluation script early gave me a baseline to measure improvements against. Without it, I would have been tuning blindly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Start simple, verify, then add complexity
&lt;/h3&gt;

&lt;p&gt;The entire system is ~200 lines of Python (excluding tests). No frameworks, no complex abstractions. This made debugging straightforward — when something went wrong, there were very few places to look.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reranker&lt;/strong&gt;: Add a cross-encoder reranker to improve ranking quality (especially for Q4 and Q9 which ranked 3rd)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid search&lt;/strong&gt;: Combine vector similarity with keyword matching (BM25) for better recall&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More data&lt;/strong&gt;: Scale from 15 to 100+ subsidies with automated collection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production frontend&lt;/strong&gt;: Migrate from Streamlit to Next.js + FastAPI for a proper web application&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you're building a RAG system for the first time, I'd recommend the same approach: &lt;strong&gt;build from scratch first, measure with real metrics, then decide if you need a framework&lt;/strong&gt;. The understanding you gain is worth far more than the time saved by a framework.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>rag</category>
      <category>showdev</category>
    </item>
    <item>
      <title>When to Use pdfme vs Jupyter for Custom Report Generation</title>
      <dc:creator>Daichi</dc:creator>
      <pubDate>Sun, 22 Mar 2026 10:28:28 +0000</pubDate>
      <link>https://dev.to/daichi_4de7a4be20102/when-to-use-pdfme-vs-jupyter-for-custom-report-generation-5g63</link>
      <guid>https://dev.to/daichi_4de7a4be20102/when-to-use-pdfme-vs-jupyter-for-custom-report-generation-5g63</guid>
      <description>&lt;p&gt;In many enterprise systems, “custom report generation” sounds simple — until it isn’t.&lt;/p&gt;

&lt;p&gt;Clients don’t just want static PDFs. They want flexibility, speed, and sometimes deep data analysis.&lt;br&gt;
The challenge is choosing the right tool for the right use case.&lt;/p&gt;

&lt;p&gt;In this article, I’ll break down two powerful approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;pdfme&lt;/strong&gt; → Best for layout-driven, self-service reports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jupyter (Python)&lt;/strong&gt; → Best for logic-heavy, data-driven reports&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 1. Use Case: pdfme (Layout Customization &amp;amp; Self-Service)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Typical Client Request
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“Can you move the logo slightly to the right?”&lt;br&gt;
“I want the remarks section to be larger.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;With &lt;strong&gt;pdfme&lt;/strong&gt;, clients can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag &amp;amp; drop elements (logo, text, tables)&lt;/li&gt;
&lt;li&gt;Adjust layout visually&lt;/li&gt;
&lt;li&gt;Instantly reflect changes in the output PDF&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 No engineering involvement required.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ When pdfme is the Right Choice
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Layout changes are the primary requirement&lt;/li&gt;
&lt;li&gt;You want &lt;strong&gt;clients to self-manage templates&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reports are &lt;strong&gt;standardized formats&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quotations&lt;/li&gt;
&lt;li&gt;Invoices&lt;/li&gt;
&lt;li&gt;Delivery notes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Speed of iteration is critical&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  💡 Why It Works
&lt;/h3&gt;

&lt;p&gt;pdfme separates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Template (layout)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data (JSON input)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it extremely flexible for non-engineers.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚀 Key Benefit
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“Empower the client to fix their own reports — instantly.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📊 2. Use Case: Jupyter (Data Processing &amp;amp; Advanced Logic)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Typical Client Request
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“Generate monthly sales reports, and extract top 10 companies into a separate sheet.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;With &lt;strong&gt;Jupyter Notebook + Pandas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aggregate and transform data&lt;/li&gt;
&lt;li&gt;Apply complex business logic&lt;/li&gt;
&lt;li&gt;Generate charts (matplotlib / seaborn)&lt;/li&gt;
&lt;li&gt;Export to PDF or Excel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Fully customizable, but requires engineering support.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ When Jupyter is the Right Choice
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Data processing is &lt;strong&gt;complex&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Each report has &lt;strong&gt;different business logic&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reports include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aggregations&lt;/li&gt;
&lt;li&gt;Rankings&lt;/li&gt;
&lt;li&gt;Forecasts&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Visualization is required (charts, graphs)&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  💡 Why It Works
&lt;/h3&gt;

&lt;p&gt;Jupyter allows you to combine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code&lt;/li&gt;
&lt;li&gt;Data&lt;/li&gt;
&lt;li&gt;Visualization&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All in one reproducible environment.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚀 Key Benefit
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“Turn raw data into insights — not just documents.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ⚖️ Side-by-Side Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;pdfme&lt;/th&gt;
&lt;th&gt;Jupyter&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary Focus&lt;/td&gt;
&lt;td&gt;Layout&lt;/td&gt;
&lt;td&gt;Data Processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;End-user (Client)&lt;/td&gt;
&lt;td&gt;Internal (Engineers)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexibility&lt;/td&gt;
&lt;td&gt;High (UI-based)&lt;/td&gt;
&lt;td&gt;Very High (Code-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintenance&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Medium–High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best For&lt;/td&gt;
&lt;td&gt;Invoices, templates&lt;/td&gt;
&lt;td&gt;Analytics reports&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧠 Decision Framework
&lt;/h2&gt;

&lt;p&gt;Ask this simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Is the complexity in the &lt;strong&gt;layout&lt;/strong&gt;, or in the &lt;strong&gt;data&lt;/strong&gt;?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;strong&gt;layout-heavy&lt;/strong&gt; → Use &lt;strong&gt;pdfme&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;If &lt;strong&gt;logic-heavy&lt;/strong&gt; → Use &lt;strong&gt;Jupyter&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔥 Real-World Insight
&lt;/h2&gt;

&lt;p&gt;In many projects, the best solution is &lt;strong&gt;not choosing one&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 Combine both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;pdfme&lt;/strong&gt; for standardized documents&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Jupyter&lt;/strong&gt; for analytical reports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation reduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineering workload&lt;/li&gt;
&lt;li&gt;Client dependency&lt;/li&gt;
&lt;li&gt;Maintenance complexity&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✍️ Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Custom report generation is not just a technical problem — it's a &lt;strong&gt;product design decision&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Choosing the wrong tool leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Endless small requests&lt;/li&gt;
&lt;li&gt;Engineering bottlenecks&lt;/li&gt;
&lt;li&gt;Frustrated clients&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choosing the right one enables:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Scalable, self-service reporting + powerful analytics&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;If you're building a reporting system, start with this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Who should control the report — the client, or the engineer?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That answer will guide your architecture.&lt;/p&gt;




</description>
      <category>automation</category>
      <category>javascript</category>
      <category>python</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Building an AI-Powered CRM Chat Assistant with n8n and OpenRouter</title>
      <dc:creator>Daichi</dc:creator>
      <pubDate>Tue, 10 Mar 2026 10:50:59 +0000</pubDate>
      <link>https://dev.to/daichi_4de7a4be20102/building-an-ai-powered-crm-chat-assistant-with-n8n-and-openrouter-338k</link>
      <guid>https://dev.to/daichi_4de7a4be20102/building-an-ai-powered-crm-chat-assistant-with-n8n-and-openrouter-338k</guid>
      <description>&lt;h1&gt;
  
  
  Build a No-Code AI CRM Assistant in One Day (n8n + Claude + OpenRouter)
&lt;/h1&gt;

&lt;p&gt;What if your team could query a CRM just by asking a question?&lt;/p&gt;

&lt;p&gt;Instead of navigating dashboards or exporting CSV files, imagine typing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Show me deals closing this month.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;…and getting the answer instantly.&lt;/p&gt;

&lt;p&gt;In this article, I'll show you how I built a &lt;strong&gt;no-code AI CRM assistant in a single day&lt;/strong&gt; that allows employees to query a CRM using natural language.&lt;/p&gt;

&lt;p&gt;The entire system runs &lt;strong&gt;without writing a single line of application code&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Tech Stack
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;n8n&lt;/strong&gt; — self-hosted workflow automation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenRouter&lt;/strong&gt; — AI model API gateway&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CRM&lt;/strong&gt; — CRM with REST API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; — container runtime&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Sonnet 4.6 (via OpenRouter)&lt;/strong&gt; — LLM powering the agent&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Architecture
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Employee] → n8n Chat UI → [AI Agent (Claude via OpenRouter)]
                                ├── Tool: Search API
                                └── Tool: Search API
                                      ↓
                         　　　    [CRM API]
                                      ↓
                        [AI generates response in Japanese]
                                      ↓
                          [Employee receives answer]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key idea is to let the &lt;strong&gt;AI agent decide which CRM API to call&lt;/strong&gt; based on the user's natural language query.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 1 — Run n8n with Docker
&lt;/h1&gt;

&lt;p&gt;Spinning up n8n locally takes only one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; n8n &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt; always &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 5678:5678 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;WEBHOOK_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://YOUR_IP:5678/ &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;N8N_EDITOR_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://YOUR_IP:5678/ &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; n8n_data:/home/node/.n8n &lt;span class="se"&gt;\&lt;/span&gt;
  n8nio/n8n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Learnings
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Authentication has changed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Older guides mention &lt;code&gt;N8N_BASIC_AUTH_*&lt;/code&gt;, but these variables are now deprecated.&lt;/p&gt;

&lt;p&gt;n8n now uses &lt;strong&gt;email-based account setup through the web UI on first launch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LAN access requires correct environment variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;WEBHOOK_URL&lt;/span&gt;
&lt;span class="err"&gt;N8N_EDITOR_BASE_URL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the chat UI may attempt to call &lt;code&gt;localhost&lt;/code&gt;, causing &lt;strong&gt;CORS errors for other users on the network&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 2 — Building the AI Agent
&lt;/h1&gt;

&lt;p&gt;Instead of a simple pipeline like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Chat → HTTP Request → AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I built a &lt;strong&gt;tool-enabled AI Agent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This allows the LLM to &lt;strong&gt;choose the correct CRM endpoint autonomously&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Workflow structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Chat Trigger → AI Agent
                ├── Tool: search
                └── Tool: search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each tool calls a specific CRM endpoint&lt;/p&gt;

&lt;p&gt;Dynamic query example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jinja"&gt;&lt;code&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nv"&gt;json.query&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Step 3 — The System Prompt (The Most Important Part)
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;system prompt determines whether the agent works reliably&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4 — Sharing on LAN
&lt;/h1&gt;

&lt;p&gt;Find your IP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ipconfig getifaddr en0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Share the chat URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;http://YOUR_IP:5678/webhook/xxxxx/chat
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable Basic Auth for security.&lt;/p&gt;




&lt;h1&gt;
  
  
  Challenges &amp;amp; Lessons Learned
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Token Limit Explosion
&lt;/h3&gt;

&lt;p&gt;Querying the CRM without filters returned the entire dataset.&lt;/p&gt;

&lt;p&gt;Result: &lt;strong&gt;8M+ tokens&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;enforce search conditions&lt;/li&gt;
&lt;li&gt;block empty queries&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Cost
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;n8n (self-hosted)&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenRouter (Claude Sonnet)&lt;/td&gt;
&lt;td&gt;~$26/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Supports roughly &lt;strong&gt;10 users × 5 queries/day&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Using &lt;strong&gt;n8n + OpenRouter&lt;/strong&gt;, I built a working AI CRM assistant &lt;strong&gt;in less than a day&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The biggest takeaway:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;System prompt design is critical.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the right guardrails, you can turn any API-driven system into a &lt;strong&gt;natural-language interface&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>llm</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The Death of SaaS: Is It Possible to Replace Software Interfaces with AI Agents?</title>
      <dc:creator>Daichi</dc:creator>
      <pubDate>Sun, 08 Mar 2026 11:10:01 +0000</pubDate>
      <link>https://dev.to/daichi_4de7a4be20102/the-death-of-saas-is-it-possible-to-replace-software-interfaces-with-ai-agents-2f3l</link>
      <guid>https://dev.to/daichi_4de7a4be20102/the-death-of-saas-is-it-possible-to-replace-software-interfaces-with-ai-agents-2f3l</guid>
      <description>&lt;p&gt;For more than a decade, &lt;strong&gt;SaaS (Software as a Service)&lt;/strong&gt; has dominated the software industry.&lt;/p&gt;

&lt;p&gt;Companies built dashboards.&lt;br&gt;
Users logged in.&lt;br&gt;
People clicked buttons to get work done.&lt;/p&gt;

&lt;p&gt;But something fundamental is changing.&lt;/p&gt;

&lt;p&gt;With the rise of &lt;strong&gt;AI agents&lt;/strong&gt;, the way we interact with software may be entering a completely new phase.&lt;/p&gt;

&lt;p&gt;Some people are now asking a provocative question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is SaaS dying?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maybe not completely — but the &lt;em&gt;way SaaS works&lt;/em&gt; is about to change dramatically.&lt;/p&gt;


&lt;h1&gt;
  
  
  The Traditional SaaS Model
&lt;/h1&gt;

&lt;p&gt;Classic SaaS follows a simple pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
 ↓
UI (dashboard)
 ↓
Software
 ↓
Business outcome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think about tools like CRM systems, analytics dashboards, or ticket management platforms.&lt;/p&gt;

&lt;p&gt;A human logs in, navigates the UI, and performs tasks manually.&lt;/p&gt;

&lt;p&gt;This model has worked incredibly well because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;software moved to the cloud&lt;/li&gt;
&lt;li&gt;companies paid subscriptions&lt;/li&gt;
&lt;li&gt;pricing scaled with the number of users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more employees a company had, the more SaaS licenses it needed.&lt;/p&gt;

&lt;p&gt;This is why &lt;strong&gt;per-seat pricing&lt;/strong&gt; became the standard.&lt;/p&gt;




&lt;h1&gt;
  
  
  AI Agents Change the Equation
&lt;/h1&gt;

&lt;p&gt;AI agents introduce a completely different model.&lt;/p&gt;

&lt;p&gt;Instead of humans operating software, &lt;strong&gt;AI can operate software directly&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human
 ↓
AI Agent
 ↓
APIs
 ↓
Software systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An AI agent can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retrieve data&lt;/li&gt;
&lt;li&gt;analyze information&lt;/li&gt;
&lt;li&gt;trigger workflows&lt;/li&gt;
&lt;li&gt;update records&lt;/li&gt;
&lt;li&gt;communicate across multiple systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All without opening a dashboard.&lt;/p&gt;

&lt;p&gt;The “user” of the software is no longer necessarily a human.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Interface Is Becoming Less Important
&lt;/h1&gt;

&lt;p&gt;Historically, SaaS companies invested heavily in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;beautiful dashboards&lt;/li&gt;
&lt;li&gt;intuitive UX&lt;/li&gt;
&lt;li&gt;complex workflow interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But AI agents don't care about dashboards.&lt;/p&gt;

&lt;p&gt;They interact with systems through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;structured data&lt;/li&gt;
&lt;li&gt;automation frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The interface was built for humans — not for machines.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As AI agents take over operational tasks, the &lt;strong&gt;value of the UI layer may decrease&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Problem With Per-Seat Pricing
&lt;/h1&gt;

&lt;p&gt;Traditional SaaS pricing assumes something important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every user is a human.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But AI agents break this assumption.&lt;/p&gt;

&lt;p&gt;Imagine a company where AI agents perform the work of multiple employees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generating reports&lt;/li&gt;
&lt;li&gt;managing tickets&lt;/li&gt;
&lt;li&gt;analyzing data&lt;/li&gt;
&lt;li&gt;updating CRM records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Does it make sense to charge &lt;strong&gt;per seat&lt;/strong&gt; anymore?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;p&gt;Future pricing models might shift toward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;task-based pricing&lt;/li&gt;
&lt;li&gt;API usage&lt;/li&gt;
&lt;li&gt;outcome-based pricing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This would fundamentally reshape the SaaS business model.&lt;/p&gt;




&lt;h1&gt;
  
  
  From Software Tools to Autonomous Systems
&lt;/h1&gt;

&lt;p&gt;Another major shift is happening.&lt;/p&gt;

&lt;p&gt;Traditional SaaS gives you &lt;strong&gt;tools&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;AI-driven systems deliver &lt;strong&gt;outcomes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of logging into five different tools, you might simply tell an AI:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Analyze our sales pipeline and generate a weekly report."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI could automatically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;retrieve CRM data&lt;/li&gt;
&lt;li&gt;analyze the pipeline&lt;/li&gt;
&lt;li&gt;generate insights&lt;/li&gt;
&lt;li&gt;produce a presentation&lt;/li&gt;
&lt;li&gt;send it to the team&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No dashboard required.&lt;/p&gt;




&lt;h1&gt;
  
  
  SaaS Isn't Dead — It's Becoming Infrastructure
&lt;/h1&gt;

&lt;p&gt;Despite the dramatic headline, SaaS probably isn't disappearing.&lt;/p&gt;

&lt;p&gt;Instead, it may evolve into something different.&lt;/p&gt;

&lt;p&gt;SaaS products may increasingly become:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;systems of record&lt;/li&gt;
&lt;li&gt;data infrastructure&lt;/li&gt;
&lt;li&gt;API platforms for AI agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The new architecture could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human
 ↓
AI Agent
 ↓
APIs
 ↓
SaaS infrastructure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this model, SaaS becomes &lt;strong&gt;the backend layer of intelligent automation&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  What This Means for Builders
&lt;/h1&gt;

&lt;p&gt;If you're building software today, the key question might no longer be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do we build a better dashboard?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead, it might be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do we build software that AI agents can operate?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means focusing on things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;robust APIs&lt;/li&gt;
&lt;li&gt;machine-readable workflows&lt;/li&gt;
&lt;li&gt;automation primitives&lt;/li&gt;
&lt;li&gt;agent-friendly architectures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most valuable products in the future may not have the best UI.&lt;/p&gt;

&lt;p&gt;They may have the &lt;strong&gt;best interfaces for AI&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Real Question
&lt;/h1&gt;

&lt;p&gt;So is SaaS dying?&lt;/p&gt;

&lt;p&gt;Maybe not.&lt;/p&gt;

&lt;p&gt;But the &lt;strong&gt;human interface layer of SaaS might be fading&lt;/strong&gt;, replaced by AI-driven automation.&lt;/p&gt;

&lt;p&gt;The future might look less like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human → SaaS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human → AI → Software
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that's true, the winners of the next decade won't just build great software.&lt;/p&gt;

&lt;p&gt;They'll build &lt;strong&gt;software that AI can drive&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;I'm curious what other engineers think.&lt;/p&gt;

&lt;p&gt;Are we witnessing &lt;strong&gt;the evolution of SaaS&lt;/strong&gt;, or &lt;strong&gt;the beginning of its replacement&lt;/strong&gt;?&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
