<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Saytu Blog</title>
    <link>https://saytu.ai/blog</link>
    <description>Notes on anime and otaku ecommerce from the team building Saytu.</description>
    <language>en</language>
    <atom:link href="https://saytu.ai/blog/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Five near-matches kept the exact product away from the model</title>
      <link>https://saytu.ai/blog/five-near-matches-kept-the-exact-product-away-from-the-model</link>
      <guid isPermaLink="true">https://saytu.ai/blog/five-near-matches-kept-the-exact-product-away-from-the-model</guid>
      <pubDate>Wed, 23 Sep 2026 10:35:11 GMT</pubDate>
      <description>Five near-matches hid the exact Shopify product from the model. We changed product search to try precise intent first, then rank 25 broad candidates before cutting the list.</description>
    </item>
    <item>
      <title>The AI started talking again. The human request stayed open.</title>
      <link>https://saytu.ai/blog/the-ai-started-talking-again-the-human-request-stayed-open</link>
      <guid isPermaLink="true">https://saytu.ai/blog/the-ai-started-talking-again-the-human-request-stayed-open</guid>
      <pubDate>Wed, 23 Sep 2026 07:38:36 GMT</pubDate>
      <description>Saytu used to leave abandoned handoffs silent forever. We changed the flow so AI can resume after staff silence while the human request stays open.</description>
    </item>
    <item>
      <title>Twenty chunks did not mean we had the whole document</title>
      <link>https://saytu.ai/blog/twenty-chunks-did-not-mean-we-had-the-whole-document</link>
      <guid isPermaLink="true">https://saytu.ai/blog/twenty-chunks-did-not-mean-we-had-the-whole-document</guid>
      <pubDate>Wed, 23 Sep 2026 02:55:05 GMT</pubDate>
      <description>Saytu could not tell whether a source at the 20-chunk cap was complete or truncated. We now record the pre-cap count so coverage is measured instead of guessed.</description>
    </item>
    <item>
      <title>Semantic retrieval was off in production, and the fallback hid it</title>
      <link>https://saytu.ai/blog/semantic-retrieval-was-off-in-production-and-the-fallback-hid-it</link>
      <guid isPermaLink="true">https://saytu.ai/blog/semantic-retrieval-was-off-in-production-and-the-fallback-hid-it</guid>
      <pubDate>Wed, 23 Sep 2026 02:55:04 GMT</pubDate>
      <description>Saytu&apos;s semantic retrieval was silently off in production while keyword fallback kept answers flowing. A backfill exposed the 401 and the environment-variable bug behind it.</description>
    </item>
    <item>
      <title>The product match was right; the card still made it look wrong</title>
      <link>https://saytu.ai/blog/the-product-match-was-right-the-card-still-made-it-look-wrong</link>
      <guid isPermaLink="true">https://saytu.ai/blog/the-product-match-was-right-the-card-still-made-it-look-wrong</guid>
      <pubDate>Tue, 22 Sep 2026 11:00:52 GMT</pubDate>
      <description>Saytu found the right product variant but showed a misleading main image. We changed the recommendation rule so variant-only matches are made explicit in the reply.</description>
    </item>
    <item>
      <title>Nine tied rows were enough to make the same question retrieve different sources</title>
      <link>https://saytu.ai/blog/nine-tied-rows-were-enough-to-make-the-same-question-retrieve-different-sources</link>
      <guid isPermaLink="true">https://saytu.ai/blog/nine-tied-rows-were-enough-to-make-the-same-question-retrieve-different-sources</guid>
      <pubDate>Mon, 21 Sep 2026 18:07:52 GMT</pubDate>
      <description>Nine tied rows made identical retrieval calls return different sources. Why the candidate window and the final ranking both needed a stable order before any quality measurement was worth running.</description>
    </item>
    <item>
      <title>Instant Avatar redraws the moving parts instead of rebuilding the whole character</title>
      <link>https://saytu.ai/blog/instant-avatar-redraws-the-moving-parts-instead-of-rebuilding-the-whole-character</link>
      <guid isPermaLink="true">https://saytu.ai/blog/instant-avatar-redraws-the-moving-parts-instead-of-rebuilding-the-whole-character</guid>
      <pubDate>Mon, 21 Sep 2026 16:43:14 GMT</pubDate>
      <description>How one illustration becomes a blinking, speaking avatar: three marked regions are redrawn and the rest of the artwork stays the bytes the merchant uploaded.</description>
    </item>
    <item>
      <title>Three ceilings a character runs into, and none of them say so</title>
      <link>https://saytu.ai/blog/three-ceilings-a-character-runs-into</link>
      <guid isPermaLink="true">https://saytu.ai/blog/three-ceilings-a-character-runs-into</guid>
      <pubDate>Mon, 21 Sep 2026 16:43:13 GMT</pubDate>
      <description>Three browser limits a Live2D renderer runs into on a storefront, what each one costs, and why none of them report themselves where they happen.</description>
    </item>
    <item>
      <title>The model only gets to paint inside three ellipses</title>
      <link>https://saytu.ai/blog/the-model-only-paints-inside-three-ellipses</link>
      <guid isPermaLink="true">https://saytu.ai/blog/the-model-only-paints-inside-three-ellipses</guid>
      <pubDate>Mon, 21 Sep 2026 10:12:20 GMT</pubDate>
      <description>How six avatar states are generated from one illustration without the character drifting, and the single step in the pipeline that gives that guarantee up.</description>
    </item>
    <item>
      <title>The metafields that crowded out the shop policies</title>
      <link>https://saytu.ai/blog/the-metafields-that-crowded-out-the-policies</link>
      <guid isPermaLink="true">https://saytu.ai/blog/the-metafields-that-crowded-out-the-policies</guid>
      <pubDate>Mon, 21 Sep 2026 06:00:18 GMT</pubDate>
      <description>Row volume is not importance. Why retrieval candidates need per-source quotas, what the numbers are, and the ceiling still left in the code on purpose.</description>
    </item>
    <item>
      <title>What verified means when a source is switched off</title>
      <link>https://saytu.ai/blog/what-verified-means-when-a-source-is-switched-off</link>
      <guid isPermaLink="true">https://saytu.ai/blog/what-verified-means-when-a-source-is-switched-off</guid>
      <pubDate>Mon, 21 Sep 2026 06:00:15 GMT</pubDate>
      <description>Turning a knowledge source off has to mean the assistant stops using it. Why row status could not carry that, and what verified actually claims.</description>
    </item>
    <item>
      <title>Four records, and what the assistant is actually shown</title>
      <link>https://saytu.ai/blog/four-records-and-what-the-assistant-is-shown</link>
      <guid isPermaLink="true">https://saytu.ai/blog/four-records-and-what-the-assistant-is-shown</guid>
      <pubDate>Mon, 21 Sep 2026 06:00:12 GMT</pubDate>
      <description>How a storefront assistant picks which parts of a merchant&apos;s own writing reach the model: four records of 520 characters, a cosine floor at 0.25, and two lanes that fail differently.</description>
    </item>
    <item>
      <title>We published 108 articles nobody read</title>
      <link>https://saytu.ai/blog/we-published-108-articles-nobody-read</link>
      <guid isPermaLink="true">https://saytu.ai/blog/we-published-108-articles-nobody-read</guid>
      <pubDate>Mon, 21 Sep 2026 06:00:10 GMT</pubDate>
      <description>108 generated articles reached our blog through an API that required only a title. What the database says about them, and the gate that now stands in the way.</description>
    </item>
    <item>
      <title>A draft should never take the live answer down</title>
      <link>https://saytu.ai/blog/a-draft-should-never-take-the-live-answer-down</link>
      <guid isPermaLink="true">https://saytu.ai/blog/a-draft-should-never-take-the-live-answer-down</guid>
      <pubDate>Mon, 21 Sep 2026 06:00:09 GMT</pubDate>
      <description>A pointer that outlived its assumption turned drafting an FAQ into an unpublish. What the status clause in the filter is really doing.</description>
    </item>
    <item>
      <title>When every score ties, the ranking is a coin flip</title>
      <link>https://saytu.ai/blog/when-every-score-ties-the-ranking-is-a-coin-flip</link>
      <guid isPermaLink="true">https://saytu.ai/blog/when-every-score-ties-the-ranking-is-a-coin-flip</guid>
      <pubDate>Mon, 21 Sep 2026 06:00:08 GMT</pubDate>
      <description>Ties in keyword retrieval made the same question return different material. Why the tiebreak is identity rather than quality, and why it had to go in twice.</description>
    </item>
    <item>
      <title>A turn id is whatever the client says it is</title>
      <link>https://saytu.ai/blog/a-turn-id-is-whatever-the-client-says-it-is</link>
      <guid isPermaLink="true">https://saytu.ai/blog/a-turn-id-is-whatever-the-client-says-it-is</guid>
      <pubDate>Mon, 21 Sep 2026 06:00:07 GMT</pubDate>
      <description>Why a client-supplied turn id can never be a key on its own, and how a lookup one field too short leaked a reply between two stores.</description>
    </item>
    <item>
      <title>Three windows, and what the assistant is allowed to keep</title>
      <link>https://saytu.ai/blog/three-windows-and-what-the-assistant-keeps</link>
      <guid isPermaLink="true">https://saytu.ai/blog/three-windows-and-what-the-assistant-keeps</guid>
      <pubDate>Mon, 21 Sep 2026 05:47:25 GMT</pubDate>
      <description>What a storefront assistant remembers about a shopper between visits, exactly: twenty-four hours of transcript, thirty days of subjects, no message text in either.</description>
    </item>
    <item>
      <title>Uploading your own Live2D model, and what actually stops you</title>
      <link>https://saytu.ai/blog/uploading-your-own-live2d-model-and-what-stops-you</link>
      <guid isPermaLink="true">https://saytu.ai/blog/uploading-your-own-live2d-model-and-what-stops-you</guid>
      <pubDate>Mon, 21 Sep 2026 04:49:24 GMT</pubDate>
      <description>The moc3 version ceiling, a 10 MB body buffer that truncates instead of erroring, and a promise that never settles: what really breaks Live2D model upload.</description>
    </item>
  </channel>
</rss>