<?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: Wouter Van Schandevijl</title>
    <description>The latest articles on DEV Community by Wouter Van Schandevijl (@laoujin).</description>
    <link>https://dev.to/laoujin</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%2F1289778%2F412a61d8-14e8-4fb7-98e6-3d93b71ea1d8.png</url>
      <title>DEV Community: Wouter Van Schandevijl</title>
      <link>https://dev.to/laoujin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/laoujin"/>
    <language>en</language>
    <item>
      <title>Building a self-hosted deep-research agent with Claude Code</title>
      <dc:creator>Wouter Van Schandevijl</dc:creator>
      <pubDate>Fri, 01 May 2026 20:01:10 +0000</pubDate>
      <link>https://dev.to/laoujin/building-a-self-hosted-deep-research-agent-with-claude-code-jha</link>
      <guid>https://dev.to/laoujin/building-a-self-hosted-deep-research-agent-with-claude-code-jha</guid>
      <description>&lt;p&gt;Every year the same problem... what to buy for her birthday. While standing in line at the bakery, I started a GitHub Issue. By the time I got back to my desk, a fancy html overview was published to my GitHub Pages with a fallback to the dry markdown research. In there was this gem "&lt;em&gt;Hunt A Killer: a six-month serialized murder-mystery&lt;/em&gt;" (she'll love that)!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qusugww09y14g6zlwiz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qusugww09y14g6zlwiz.gif" alt="Atlas published page" width="600" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/Laoujin/Scout" rel="noopener noreferrer"&gt;Scout&lt;/a&gt;, a MIT open-source research engine that runs Claude Code on your hardware and takes your one-line topic from a GitHub Issue to a cited markdown on a site you own. This post is about the four design decisions that made it actually useful, not just a demo.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pain
&lt;/h2&gt;

&lt;p&gt;I wanted a research loop that fits the way ideas arrive.&lt;/p&gt;

&lt;p&gt;Most of my research curiosities show up on a phone — on a train, in line, mid-conversation. I'd then act on the result at my desk, often inside a Claude Code session, using the research as context for whatever I'm building. The loop I wanted: on the go capture, desk-side payoff.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is, in one diagram
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3b5phm34e1nutg1kbb1n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3b5phm34e1nutg1kbb1n.png" alt="Scout flow" width="719" height="876"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;→ Open a GitHub Issue&lt;br&gt;
→ Sharpen &amp;amp; Sub-Topics selection (optional)&lt;br&gt;
→ Fancy HTML pages selection (optional)&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision 1: GitHub Issues as the UX
&lt;/h2&gt;

&lt;p&gt;Thank you GitHub for not having to build a UI!&lt;br&gt;&lt;br&gt;
I already have the account, it's tightly linked with the source code,&lt;br&gt;
gave me Auth, and a way to converse with Claude Code and checkboxes to&lt;br&gt;
get Claude started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision 2: Sharpen before research
&lt;/h2&gt;

&lt;p&gt;The biggest single quality lever in the system isn't the model or the search backend — it's the sharpening step that runs &lt;strong&gt;before&lt;/strong&gt; any research starts.&lt;/p&gt;

&lt;p&gt;A user types "best NAS to buy in 2026." That's three different questions in a trench coat: best for what budget? Replacing what? Optimizing for storage capacity, idle wattage, or both? Without sharpening, Claude charges off in one direction and the output ignores two thirds of what the user actually meant.&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;skills/scout/sharpen.md&lt;/code&gt; runs first: read the topic, propose a tightened framing as a comment ("Survey for replacing a Synology NAS in 2026, optimised for AVX2 + ECC, comparing UGREEN / Beelink / Minisforum and TrueNAS / Unraid / Proxmox…"), wait for &lt;code&gt;tick ✓&lt;/code&gt; or a steering reply. Only then does research start.&lt;/p&gt;

&lt;p&gt;The lesson generalizes: &lt;strong&gt;agents that ask one clarifying question before working produce output an order of magnitude better than agents that don't.&lt;/strong&gt; Sharpening is cheap (one model call), and it eliminates the most common (and expensive!) failure mode — answering the wrong question.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision 3: Decompose wide topics into parallel sub-agent expeditions
&lt;/h2&gt;

&lt;p&gt;Some questions are atomic ("best static-site generator in 2026"). Some are containers ("everything I need to leave Synology"). Trying to answer the latter in one pass produces a 4-page jumble.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;expedition&lt;/code&gt; depth, the sharpener also proposes 2–8 sub-topics ("hardware shortlist", "OS/storage stack", "DSM migration playbook", "remote access"). Each becomes its own independent expedition, dispatched as a sub-agent in parallel. After they all finish, a synthesis pass produces a parent overview page that links each child.&lt;/p&gt;

&lt;p&gt;This is map-reduce, but applied at the &lt;em&gt;research-question&lt;/em&gt; level rather than the data level. Two non-obvious things matter:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sub-topics must be independently coherent.&lt;/strong&gt; If sub-topic 3 needs sub-topic 1's conclusions, you've decomposed wrong — collapse them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The synthesis pass is where most value lives.&lt;/strong&gt; Without it, you have N disconnected pages. With it, the parent page reconciles disagreements between children and ends with a recommendation.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Decision 4: "Every claim carries its URL inline" as a skill rule
&lt;/h2&gt;

&lt;p&gt;The single rule that does the most work: every factual claim, number, or quote must have its source URL &lt;strong&gt;next to the claim&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why: when claims and citations are decoupled, LLMs hallucinate. The citations look real, but they don't actually back the specific sentence above them. Forcing inline URLs (&lt;code&gt;[[1]](https://...)&lt;/code&gt;) turns hallucination into a typing constraint the model can't fudge. If it can't find a URL, it can't make the claim.&lt;/p&gt;

&lt;p&gt;This rule is enforced in &lt;code&gt;skills/scout/SKILL.md&lt;/code&gt; and re-injected on every output pass. It's the cheapest, most effective hallucination-defense I've shipped in any agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;Measured per-run from my own Atlas (Sonnet 4.6 API):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Cost median (range)&lt;/th&gt;
&lt;th&gt;n&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;recon&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;one-page&lt;/td&gt;
&lt;td&gt;~2 min&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$0.83&lt;/strong&gt; ($0.73–$0.93)&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;survey&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;single page&lt;/td&gt;
&lt;td&gt;5–10 min&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$2.56&lt;/strong&gt; ($1.99–$3.99)&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;expedition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;single deep&lt;/td&gt;
&lt;td&gt;12–20 min&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$8.64&lt;/strong&gt; ($7.23–$14.90)&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;expedition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;multi-angle&lt;/td&gt;
&lt;td&gt;35–70 min&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$28&lt;/strong&gt; ($12–$35)&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On a Pro/Max subscription, runs consume your existing quota — no incremental cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/Laoujin/Scout/main/install.sh &lt;span class="se"&gt;\&lt;/span&gt;
  | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;s5.cartography.v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/Laoujin/Scout" rel="noopener noreferrer"&gt;github.com/Laoujin/Scout&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live example Atlas: &lt;a href="https://laoujin.github.io/Atlas/" rel="noopener noreferrer"&gt;laoujin.github.io/Atlas&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Landing page &amp;amp; config picker: &lt;a href="https://laoujin.github.io/Scout/" rel="noopener noreferrer"&gt;laoujin.github.io/Scout&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Sharpen first. Decompose wide topics. Inline citations as a hard rule. Use GitHub Issues so you don't build a UI. Those four ideas port to any agent that produces long-form output — the rest of Scout is plumbing.&lt;/p&gt;

&lt;p&gt;MIT-licensed, three-repo split (Scout / Atlas / Compass), one-line install. Fork it, take the patterns, make it your own.&lt;/p&gt;

&lt;p&gt;⭐ &lt;a href="https://github.com/Laoujin/Scout" rel="noopener noreferrer"&gt;github.com/Laoujin/Scout&lt;/a&gt; if you'd find this useful — that's the signal that tells me whether to keep building.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
