<?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: Monsiu Tech</title>
    <description>The latest articles on DEV Community by Monsiu Tech (@monsiutech).</description>
    <link>https://dev.to/monsiutech</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%2F4022997%2Fc30bc8e8-b1f4-4d8a-be6b-64890ebf3d4e.jpg</url>
      <title>DEV Community: Monsiu Tech</title>
      <link>https://dev.to/monsiutech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/monsiutech"/>
    <language>en</language>
    <item>
      <title>I built an AI contract reviewer that has to cite its sources. Here's the architecture.</title>
      <dc:creator>Monsiu Tech</dc:creator>
      <pubDate>Thu, 09 Jul 2026 15:44:44 +0000</pubDate>
      <link>https://dev.to/monsiutech/i-built-an-ai-contract-reviewer-that-has-to-cite-its-sources-heres-the-architecture-40ek</link>
      <guid>https://dev.to/monsiutech/i-built-an-ai-contract-reviewer-that-has-to-cite-its-sources-heres-the-architecture-40ek</guid>
      <description>&lt;p&gt;AI contract summaries share one flaw: you can't tell when they're wrong. The model says "this lease has an aggressive auto-renewal," and you either trust it or read the whole contract anyway, which defeats the point.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://clauseshift.com" rel="noopener noreferrer"&gt;ClauseShift&lt;/a&gt; around one rule: &lt;strong&gt;every risk it flags must quote the exact clause it came from, verbatim.&lt;/strong&gt; If the model can't point to the wording, it doesn't get to make the claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cross-check architecture
&lt;/h2&gt;

&lt;p&gt;The interesting part is the premium pass: &lt;strong&gt;two models (Gemini 3.1 Pro and DeepSeek V4) review the same contract in parallel&lt;/strong&gt;, then a consolidation step merges their findings and computes a combined risk score. Where they disagree, the report says so instead of hiding it. Disagreement between models turns out to be signal, not noise: if only one model flags a clause, that's a "read this yourself" marker.&lt;/p&gt;

&lt;p&gt;A few hard-won lessons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Structured output needs an escape hatch.&lt;/strong&gt; Both models return JSON memos (findings, risk enums, key dates). The JSON keys and risk levels stay English even when the report language is German or Japanese; only the prose is localized. Mixing schema and language in one instruction was the #1 source of malformed output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Fallback chains fail silently.&lt;/strong&gt; My last-resort fallback (direct Gemini Flash) was broken in production for weeks and I only found out by deliberately breaking my primary API key in a test. The bug: Gemini 2.5+ are thinking models, and the thinking tokens consumed the entire output budget, so responses came back empty. One thinkingBudget cap fixed it. Test your fallbacks by breaking things on purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Fairness beats margins.&lt;/strong&gt; If one of the two premium models fails mid-run, the user gets the surviving model's report, a notice that it fell back, and their credit is not charged. That policy cost me an hour to build and is the kind of thing that makes people trust a paid product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web&lt;/strong&gt;: Next.js (App Router) on Railway, one app serving the marketing site and the product split by hostname in middleware&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile&lt;/strong&gt;: Flutter, one codebase for Android (Play, Amazon, Huawei) with per-store billing behind build flags&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data&lt;/strong&gt;: Supabase (auth + entitlements), reports stored on-device by default with opt-in sync&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payments&lt;/strong&gt;: Paystack on web, native billing in each store&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Privacy design
&lt;/h2&gt;

&lt;p&gt;Contracts are the documents people least want in a chatbot log. So: no training on user contracts, uploaded files are not retained after the review, reports live on the device unless you opt into sync, and account deletion actually deletes.&lt;/p&gt;

&lt;p&gt;The free tier is 3 reviews a month (no card). If you review contracts regularly, I'd genuinely like to know where it falls short: the two-model cross-check either earns your trust or it's just doubled inference cost, and I want to find out which.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nextjs</category>
      <category>flutter</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
