<?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: Zero AI Developer</title>
    <description>The latest articles on DEV Community by Zero AI Developer (@zero-ai-developer).</description>
    <link>https://dev.to/zero-ai-developer</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%2F4114513%2Fd7e928b4-026f-470c-b38e-e5b55e63f080.png</url>
      <title>DEV Community: Zero AI Developer</title>
      <link>https://dev.to/zero-ai-developer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zero-ai-developer"/>
    <language>en</language>
    <item>
      <title>Handwritten faxes, tilted phone-camera receipts, messy PDFs — I built an AI pipeline that turns them all into clean structured data</title>
      <dc:creator>Zero AI Developer</dc:creator>
      <pubDate>Tue, 08 Sep 2026 08:06:38 +0000</pubDate>
      <link>https://dev.to/zero-ai-developer/handwritten-faxes-tilted-phone-camera-receipts-messy-pdfs-i-built-an-ai-pipeline-that-turns-2kl</link>
      <guid>https://dev.to/zero-ai-developer/handwritten-faxes-tilted-phone-camera-receipts-messy-pdfs-i-built-an-ai-pipeline-that-turns-2kl</guid>
      <description>&lt;p&gt;Handwritten fax orders. Receipts photographed at an angle on a phone. PDFs that all use different layouts. I built a small pipeline using Claude Code that reads all of these and turns them into one clean, structured spreadsheet — and I want to walk through exactly how it performed, including where it broke.&lt;/p&gt;

&lt;p&gt;This is meant to demonstrate something a lot of back-office teams deal with every day: manually copying information from paper/photos/scans into a spreadsheet. How far can AI actually take that job?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pipeline
&lt;/h2&gt;

&lt;p&gt;The idea is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Watch a folder
      ↓
Detect a new file (PDF/image)
      ↓
Have Claude read it
      ↓
Extract company name, date, line items, quantities, and totals as JSON
      ↓
Append to one CSV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key point: &lt;strong&gt;the same pipeline handles all of these regardless of how messy the input looks.&lt;/strong&gt; I deliberately generated three very different test files:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A clean, well-formatted PDF (fictional purchase order, 3 line items)&lt;/li&gt;
&lt;li&gt;A receipt that looks like it was photographed on a phone at an angle (tilt, shadow, JPEG artifacts)&lt;/li&gt;
&lt;li&gt;A fax-style image with handwriting (broken layout, faded text, noise)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;All three files produced results that &lt;strong&gt;matched the source content exactly&lt;/strong&gt;. Total processing time for all three: about 25 seconds (roughly 5–10 seconds per file).&lt;/p&gt;

&lt;p&gt;Here's a sample of what came out (all company names are fictional test data):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source file&lt;/th&gt;
&lt;th&gt;Vendor&lt;/th&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Qty&lt;/th&gt;
&lt;th&gt;Unit price&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;fax_handwritten.png&lt;/td&gt;
&lt;td&gt;(fictional)&lt;/td&gt;
&lt;td&gt;8/20&lt;/td&gt;
&lt;td&gt;Cardboard box, size 60&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;@98&lt;/td&gt;
&lt;td&gt;approx. ¥62,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fax_handwritten.png&lt;/td&gt;
&lt;td&gt;(fictional)&lt;/td&gt;
&lt;td&gt;8/20&lt;/td&gt;
&lt;td&gt;Cloth tape 50m&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;@340&lt;/td&gt;
&lt;td&gt;approx. ¥62,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;order_clean.pdf&lt;/td&gt;
&lt;td&gt;(fictional)&lt;/td&gt;
&lt;td&gt;Aug 21, 2026&lt;/td&gt;
&lt;td&gt;A4 copy paper, 500 sheets&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;¥520&lt;/td&gt;
&lt;td&gt;¥38,720&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;receipt_photo.jpg&lt;/td&gt;
&lt;td&gt;(fictional)&lt;/td&gt;
&lt;td&gt;Aug 19, 2026&lt;/td&gt;
&lt;td&gt;USB drive 64GB&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;1,280&lt;/td&gt;
&lt;td&gt;¥15,334&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What I find most interesting is the handwritten fax row. Notice "@98" and "approx. ¥62,000" — &lt;strong&gt;it preserved the ambiguity of the handwritten notation exactly as written&lt;/strong&gt;, instead of silently converting it into a clean number. That's by design: the extraction prompt explicitly instructs the model not to guess when something is genuinely ambiguous. Quietly "fixing" ambiguous handwriting into a confident-looking number would actually make this system more dangerous in a real back-office setting, not less.&lt;/p&gt;

&lt;p&gt;All three files also correctly identified the &lt;strong&gt;issuing vendor rather than the addressee&lt;/strong&gt; as the vendor field — a sign this isn't naive OCR, it's actually reasoning about document structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Running through a Claude Code subscription instead of metered API calls
&lt;/h3&gt;

&lt;p&gt;I originally called the Anthropic API directly, but switched to invoking the &lt;strong&gt;Claude Code CLI as a subprocess&lt;/strong&gt; instead. Simple reason: I didn't want to rack up API costs while still validating the idea.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;extraction prompt&amp;gt;"&lt;/span&gt; &lt;span class="nt"&gt;--allowed-tools&lt;/span&gt; Read &lt;span class="nt"&gt;--output-format&lt;/span&gt; json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each file is processed as a separate, non-interactive CLI call. Using &lt;code&gt;--output-format json&lt;/code&gt; gives you a structured envelope (with fields like &lt;code&gt;is_error&lt;/code&gt;, &lt;code&gt;result&lt;/code&gt;) that's much more robust to parse than raw stdout.&lt;/p&gt;

&lt;p&gt;This does come with a real limitation: spinning up a new process per file doesn't scale to bulk processing. If you need to run hundreds of documents at once, going back to the metered API is the more sensible choice. For a small-scale demo like this, that tradeoff is fine.&lt;/p&gt;

&lt;h3&gt;
  
  
  A bug I found the hard way: "failure" wasn't actually being treated as failure
&lt;/h3&gt;

&lt;p&gt;While testing, I found a real gap in the design. When you feed it a corrupted file, Claude correctly returns all fields as &lt;code&gt;null&lt;/code&gt;, per the instructions. The problem: that was being treated as a "success" — an empty row got appended to the CSV, and the source file got moved into the "processed" folder and effectively disappeared.&lt;/p&gt;

&lt;p&gt;That meant a failure could silently destroy the only copy of that file's data, with no error surfaced. I fixed this by treating "all key fields are null" as an error case, so failed files stay in the input queue for retry instead of vanishing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is actually useful for
&lt;/h2&gt;

&lt;p&gt;The point of this demo isn't "it can read purchase orders." It's that &lt;strong&gt;work assumed to require manual handling — because every input looks different — can actually be automated with AI, with reasonable reliability.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same pattern applies to things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reconciling invoices that use a different format for every vendor&lt;/li&gt;
&lt;li&gt;Digitizing orders that only ever arrive by fax&lt;/li&gt;
&lt;li&gt;Turning paper forms/surveys into structured data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're trying to figure out how to actually wire this kind of thing into a real business process — not just "chat with an AI," but an actual pipeline — I take on contract work designing and implementing systems like this. Feel free to reach out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;This was a small-scale demo, not a production system. But it validated something real: turning messy, inconsistent input into meaningful structured data — a boring but very common back-office problem — is something AI can genuinely do today, not just in theory.&lt;/p&gt;

&lt;p&gt;Hope this is useful if you're exploring something similar.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I Tried to Build a Company Where AI Autonomously Finds, Wins, and Delivers Work. Here's Why It Failed.</title>
      <dc:creator>Zero AI Developer</dc:creator>
      <pubDate>Tue, 08 Sep 2026 06:12:03 +0000</pubDate>
      <link>https://dev.to/zero-ai-developer/i-tried-to-build-a-company-where-ai-autonomously-finds-wins-and-delivers-work-heres-why-it-5f3c</link>
      <guid>https://dev.to/zero-ai-developer/i-tried-to-build-a-company-where-ai-autonomously-finds-wins-and-delivers-work-heres-why-it-5f3c</guid>
      <description>&lt;p&gt;"Just tell Claude Code what to do, and let AI handle everything — finding leads, qualifying them, doing the work, and delivering it."&lt;/p&gt;

&lt;p&gt;That was the idea I spent about half a year trying to build, on my own. Spoiler: the system worked. All the tests passed. And I still ended up with &lt;strong&gt;zero contracts, zero dollars earned, and a net loss&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this post I'll walk through the actual architecture I built, what happened across two experiment cycles, and why "being able to build it" turned out to be a completely different problem from "being able to sell it." I'm writing this in the hope that it saves someone else from repeating the same mistake.&lt;/p&gt;

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

&lt;p&gt;I designed a 4-stage pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Research Agent (find opportunities)
      ↓
Qualification Agent (score them)
      ↓
Delivery Agent (execute &amp;amp; deliver)
      ↓
Ledger (log everything, track KPIs)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Research Agent
&lt;/h3&gt;

&lt;p&gt;This agent searches for potential work based on a configurable domain, keywords, geography, and criteria. One important design decision: none of these were hardcoded. I wanted to be able to pivot the target domain without touching the code, since I fully expected the first domain to fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Qualification Agent
&lt;/h3&gt;

&lt;p&gt;Every candidate opportunity gets scored on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Willingness to pay&lt;/strong&gt; — is there real evidence someone would actually pay this amount?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Existing alternatives&lt;/strong&gt; — could this be solved with a free tool or in-house resources already?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reachability&lt;/strong&gt; — can I actually contact this person/company?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk factors&lt;/strong&gt; — reputational or terms-of-service risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I iterated on this scoring logic quite a bit. For example, I changed the risk-score weight from &lt;code&gt;-3&lt;/code&gt; to &lt;code&gt;-5&lt;/code&gt; partway through, so that an extremely risky candidate could single-handedly sink an otherwise strong score below the pass line.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Delivery Agent
&lt;/h3&gt;

&lt;p&gt;Once a job was won, this agent used the Claude Code CLI as the execution engine to produce the deliverable. I deliberately avoided metered API billing and ran everything within an existing Claude Code subscription — I didn't want to rack up AI costs before earning a single dollar.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Ledger
&lt;/h3&gt;

&lt;p&gt;Every opportunity, from discovery to outcome, gets logged. To avoid the trap of "this feels like it's working," I tracked exactly six KPIs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;KPI&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Opportunities discovered&lt;/td&gt;
&lt;td&gt;Number of candidate jobs found&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jobs completed&lt;/td&gt;
&lt;td&gt;Number of jobs actually finished&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revenue generated&lt;/td&gt;
&lt;td&gt;Cash actually received (not invoices, not verbal agreements)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI cost&lt;/td&gt;
&lt;td&gt;Cost of AI usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human time&lt;/td&gt;
&lt;td&gt;Hours of human involvement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revenue per human hour&lt;/td&gt;
&lt;td&gt;Revenue ÷ human hours&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Deliberately excluding vanity metrics like signups or pageviews was, in hindsight, the right call. But as you'll see below, having the right metrics doesn't help much when the actual number of jobs is zero.&lt;/p&gt;

&lt;p&gt;I also wrote 300+ tests. Engineering-wise, this system was solid.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cycle 1: Let AI Discover Opportunities on Its Own → 10 Found, 0 Won
&lt;/h2&gt;

&lt;p&gt;In the first cycle, I let the Research Agent autonomously search for opportunities from scratch. Results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Opportunities discovered: 10&lt;/li&gt;
&lt;li&gt;Passed qualification: 0&lt;/li&gt;
&lt;li&gt;Won: 0&lt;/li&gt;
&lt;li&gt;Revenue: $0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Digging into why all 10 failed, every single one fell into at least one of these buckets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Willingness to pay was pure speculation.&lt;/strong&gt; The pricing was based on "this seems like a reasonable amount," with zero evidence anyone had actually transacted at that price.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A free alternative always existed.&lt;/strong&gt; Every candidate task could already be solved with a free tool or existing in-house resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No evidence of reachability.&lt;/strong&gt; There was no verification that I could actually contact these targets, let alone pitch them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In short: the AI found opportunities that looked plausible on paper, but none of them connected to a real person who was actually struggling with the problem and willing to pay to solve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Course Correction: Human Finds Jobs, AI Just Verifies Them
&lt;/h2&gt;

&lt;p&gt;After Cycle 1, I flipped the division of labor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Human&lt;/strong&gt;: manually finds real job postings on freelance/gig platforms — real budgets, real clients&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI&lt;/strong&gt;: only does supporting research on those human-sourced listings (e.g., checking if the asking price is reasonable)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was a big shift — from "AI does discovery" to "discovery is human, AI only reinforces."&lt;/p&gt;

&lt;h3&gt;
  
  
  The Anonymity Wall I Didn't Expect
&lt;/h3&gt;

&lt;p&gt;While comparing platforms at this stage, I hit a wall I hadn't anticipated: &lt;strong&gt;wanting to stay anonymous (no real name, no face photo) massively narrowed the field of usable platforms.&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;Requirement&lt;/th&gt;
&lt;th&gt;Outcome&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Real name + photo mandatory&lt;/td&gt;
&lt;td&gt;Excluded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pseudonym/business name OK, but requires ID + selfie verification&lt;/td&gt;
&lt;td&gt;Skipped — too much friction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anonymous-friendly, lightweight verification&lt;/td&gt;
&lt;td&gt;Kept as a candidate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I also concluded that having AI autonomously crawl sites to find jobs was in a legal/ToS gray zone. In fact, one platform I was evaluating later discontinued its "auto-propose" feature entirely, switching to a "human must review before proposing" model. I took that as external confirmation that fully autonomous bot applications carry real platform risk.&lt;/p&gt;

&lt;p&gt;What I ended up building instead: save search filters, receive email notifications for new listings, and have the AI read and analyze those notifications — never touching the site directly. It avoids ToS risk while still using AI for the analysis part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cycle 2 Results, and Why It Still Didn't Work
&lt;/h2&gt;

&lt;p&gt;Even with this more careful setup, Cycle 2 also ended in zero contracts and zero revenue.&lt;/p&gt;

&lt;p&gt;Technically, everything worked exactly as designed — the qualification logic, a "Policy Gate" that automatically filtered out sites with no-solicitation notices or bot bans, and the logging pipeline all functioned correctly.&lt;/p&gt;

&lt;p&gt;The problem was never engineering. &lt;strong&gt;Winning work is not a problem software can solve.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a person or company decides to hire someone, the deciding factor isn't "is this AI technically impressive?" It's "can I trust this person/company to actually deliver?" Trust comes from track record, referrals, and prior relationships — not something an automated system can manufacture on your behalf.&lt;/p&gt;

&lt;p&gt;Looking back, I was essentially betting on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build it → put it out there → someone finds it&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the "someone finds it" part was where the whole plan broke down. Interestingly, I'd hit the exact same wall before, with a content site that depended on search traffic, and with several mobile apps I'd shipped — same structural problem every time. I could build things. I had never actually designed a distribution channel.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm Doing With This Now
&lt;/h2&gt;

&lt;p&gt;The original vision — "AI autonomously wins its own business" — is on hold indefinitely.&lt;/p&gt;

&lt;p&gt;But the engineering work itself — designing and implementing a full discover → qualify → execute → log pipeline — wasn't wasted. I'm now repositioning that same technical capability: instead of using it to run my own autonomous business, I'm offering it as implementation work for companies that want to build AI-driven automation into their own operations.&lt;/p&gt;

&lt;p&gt;Concretely, this includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designing and building AI agent systems with Claude Code&lt;/li&gt;
&lt;li&gt;Building automation pipelines that combine LLMs and APIs (scoring logic, risk evaluation, logging/dashboards — end to end)&lt;/li&gt;
&lt;li&gt;Solo end-to-end iOS app development, from concept through App Store release (shipped 9 so far)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're trying to figure out how to actually wire AI into a real workflow — beyond just prompting a chatbot — feel free to reach out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Building something that automatically earns you money is a genuinely exciting idea for any indie developer. And with today's AI tooling, building a technically functional system is very achievable solo.&lt;/p&gt;

&lt;p&gt;What I underestimated was the gap between "a system that correctly does what it's designed to do" and "a system that convinces someone to actually pay for it." That gap isn't closed with more code — it's closed with trust, built the slow way.&lt;/p&gt;

&lt;p&gt;Hope this is useful to anyone chasing a similar idea.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>automation</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
