<?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: ssapable</title>
    <description>The latest articles on DEV Community by ssapable (@ssapable).</description>
    <link>https://dev.to/ssapable</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%2F4153318%2F112b35c3-b13c-474d-90b6-6542ca86b1e3.jpg</url>
      <title>DEV Community: ssapable</title>
      <link>https://dev.to/ssapable</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ssapable"/>
    <language>en</language>
    <item>
      <title>How I made my AI agents learn from every approve, edit and reject</title>
      <dc:creator>ssapable</dc:creator>
      <pubDate>Thu, 01 Oct 2026 12:58:46 +0000</pubDate>
      <link>https://dev.to/ssapable/how-i-made-my-ai-agents-learn-from-every-approve-edit-and-reject-4pdo</link>
      <guid>https://dev.to/ssapable/how-i-made-my-ai-agents-learn-from-every-approve-edit-and-reject-4pdo</guid>
      <description>&lt;p&gt;I run a one-person education business in Korea, and AI agents (Claude Code, Codex) write most of my first drafts: posts, replies to comments, product pages.&lt;/p&gt;

&lt;p&gt;For a while they kept making the same mistakes. One agent turns notes I send it on Telegram into social posts, and it kept adding lines like "when I tried this with my clients..." when nothing in my notes said that. Reads great, totally made up. I'd fix it, and the next session would do it again, because my corrections lived in a chat the next session never saw.&lt;/p&gt;

&lt;p&gt;The fix turned out to be boring: a feedback table, a split between rules and memory, and a button on my phone. My setup has logged 440 agent runs and about 250 pieces of feedback so far. Here's the minimal version, schema included.&lt;/p&gt;

&lt;p&gt;This is the loop running in a browser tab: a real Postgres + pgvector via PGlite, plus a small embedding model, nothing to install and no API key. "Can I get it wrapped as a present?" pulls in an earlier gift-wrap rejection even though the two share no words, and after I store one edit, a new question about unscented candles pulls in that correction:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7c1ejliziw7fiszcxdzt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7c1ejliziw7fiszcxdzt.gif" alt="Browser demo of the feedback loop" width="720" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://ssap-pa.github.io/self-learning-agent-setup/" rel="noopener noreferrer"&gt;try it yourself&lt;/a&gt; and add your own decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two layers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. What the agent knows (knowledge layer)&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;Type&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Where it lives&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Constants&lt;/td&gt;
&lt;td&gt;brand, voice, customers, founder story&lt;/td&gt;
&lt;td&gt;Markdown files in a &lt;code&gt;brand/&lt;/code&gt; folder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Variables&lt;/td&gt;
&lt;td&gt;price, stock, seats, schedule&lt;/td&gt;
&lt;td&gt;your site's database, read live&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large knowledge&lt;/td&gt;
&lt;td&gt;lessons, ebooks, FAQs&lt;/td&gt;
&lt;td&gt;same database, embedded for search&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The rule I learned the hard way: files for who you are, database for what's true right now. A price in a text file goes stale, and the agent quotes last month's promo with total confidence. And the agent can only say what your admin page stores. "3 seats left" needs a seats field.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. How it improves (learning loop)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Store every approve (+1), reject (-1) and edit (0, with the correction), linked to the run it judges&lt;/li&gt;
&lt;li&gt;Repeated feedback becomes a &lt;em&gt;candidate&lt;/em&gt; rule, not an active one&lt;/li&gt;
&lt;li&gt;Score candidates against a rubric for that goal&lt;/li&gt;
&lt;li&gt;Compare against current behavior&lt;/li&gt;
&lt;li&gt;Promote or drop&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The schema
&lt;/h2&gt;

&lt;p&gt;Postgres / Supabase with pgvector. Three tables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;schema&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;agent_learning&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;agent_learning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;goal&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="s1"&gt;'running'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;started_at&lt;/span&gt; &lt;span class="n"&gt;timestamptz&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;agent_learning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feedback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;run_id&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="k"&gt;references&lt;/span&gt; &lt;span class="n"&gt;agent_learning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;rating&lt;/span&gt; &lt;span class="nb"&gt;smallint&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="k"&gt;check&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt; &lt;span class="k"&gt;between&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;correction&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="s1"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1536&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;timestamptz&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;agent_learning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="s1"&gt;'candidate'&lt;/span&gt;
    &lt;span class="k"&gt;check&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'candidate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'active'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'retired'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="n"&gt;evidence&lt;/span&gt; &lt;span class="n"&gt;jsonb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;timestamptz&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep this schema private. Don't expose it through your public API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capturing feedback: a button, not a chat
&lt;/h2&gt;

&lt;p&gt;A Telegram bot sends each draft to my phone with Approve / Reject / Edit buttons. The button handler writes one row to &lt;code&gt;feedback&lt;/code&gt; with the run it belongs to. Edits go in as &lt;code&gt;rating = 0&lt;/code&gt; with the corrected text in &lt;code&gt;correction&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The bug that cost me the most: for a while approvals were &lt;strong&gt;silently not being stored&lt;/strong&gt;. The bot logged the tap, the learning table never got the row, and nothing complained. Check it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;agent_learning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feedback&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;interval&lt;/span&gt; &lt;span class="s1"&gt;'1 day'&lt;/span&gt;
&lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you tapped approve ten times today and this says zero, the loop is broken no matter how good the rest looks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using feedback at draft time
&lt;/h2&gt;

&lt;p&gt;Before the agent writes, pull two things into its context: active rules, and past corrections from &lt;em&gt;similar&lt;/em&gt; situations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- $1 = embedding of the new task, e.g. "reply to a comment asking about pricing"&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;correction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rating&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;agent_learning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feedback&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;correction&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;limit&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My first version used keyword search, and it missed feedback phrased differently ("too stiff" vs "sounds like a robot"). Embedding search fixed that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rules vs. memory
&lt;/h2&gt;

&lt;p&gt;This split made the biggest difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rules&lt;/strong&gt; always apply. "Never invent a client story" is a rule.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt; only applies when the situation matches. "No emojis on condolence replies" shouldn't touch every post.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Memories that keep coming back get proposed as rules. Rules that start getting overridden get retired. Nothing is promoted automatically: a candidate needs repeated evidence, and I can still say no.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two more things that broke
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Two bots, one token.&lt;/strong&gt; I had one bot for comment replies and wanted a second for notes-to-posts. Same Telegram token meant both polled for updates and ate each other's messages. They had to be separate bots, but both still hand off to one shared publish function, so the spacing rules (3 posts a day max, 3 hours apart) live in one place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules in AGENTS.md get skipped.&lt;/strong&gt; If a program runs on its own, enforce the rule in code. A line in a prompt file is a suggestion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Start small
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One goal, low limits. Mine started at 1 post and up to 3 replies a day for two weeks.&lt;/li&gt;
&lt;li&gt;Keep approval on until there's nothing left to correct.&lt;/li&gt;
&lt;li&gt;Measure purchases or signups, not likes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Try the loop in your browser (Postgres + pgvector running in the tab, nothing to install): &lt;a href="https://ssap-pa.github.io/self-learning-agent-setup/" rel="noopener noreferrer"&gt;https://ssap-pa.github.io/self-learning-agent-setup/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repo with the schema, a one-minute demo you can run with no database (&lt;code&gt;cd demo &amp;amp;&amp;amp; npm install &amp;amp;&amp;amp; npm run demo&lt;/code&gt;), and the prompts I used to get the agents to build this themselves: &lt;a href="https://github.com/ssap-pa/self-learning-agent-setup" rel="noopener noreferrer"&gt;https://github.com/ssap-pa/self-learning-agent-setup&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Same loop as an MCP server for Claude Code, Cursor or Claude Desktop (local Postgres, nothing to host): &lt;code&gt;claude mcp add feedback-memory -- npx -y github:ssap-pa/self-learning-agent-setup&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The complete working version (Python and TypeScript library + CLI, Telegram approval bot, rule proposals, an MCP server on your own Postgres / Supabase, 27 tests): &lt;a href="https://payhip.com/b/grc25" rel="noopener noreferrer"&gt;https://payhip.com/b/grc25&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Free 23-page field guide with a worked example and a 7-day plan: &lt;a href="https://payhip.com/b/QHgfJ" rel="noopener noreferrer"&gt;https://payhip.com/b/QHgfJ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A free 22-minute video lesson where I build this system with an agent (Korean audio, English subtitles, no account): &lt;a href="https://ssapable.com/courses/ai-agent?lang=en&amp;amp;utm_source=devto&amp;amp;utm_medium=article1#free-preview" rel="noopener noreferrer"&gt;https://ssapable.com/courses/ai-agent?lang=en&amp;amp;utm_source=devto&amp;amp;utm_medium=article1#free-preview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The book this comes from, &lt;em&gt;Just Say "Do It"&lt;/em&gt; (English edition of my Korean course): &lt;a href="https://payhip.com/b/xmZvu" rel="noopener noreferrer"&gt;https://payhip.com/b/xmZvu&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Side note: right now I'm letting Claude Code try to make $1,000 from people outside Korea in 72 hours with this exact setup, no ads. I'm posting the real numbers on X as it goes: &lt;a href="https://x.com/deombeulsa54847/status/2105464212567040411" rel="noopener noreferrer"&gt;https://x.com/deombeulsa54847/status/2105464212567040411&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you follow me there, the book is free for the first 100 people with code FIRST100: &lt;a href="https://x.com/deombeulsa54847/status/2105507513475219888" rel="noopener noreferrer"&gt;https://x.com/deombeulsa54847/status/2105507513475219888&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>postgres</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
