<?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: Shuo Wu</title>
    <description>The latest articles on DEV Community by Shuo Wu (@shuo_wu_00d47f641aed077d6).</description>
    <link>https://dev.to/shuo_wu_00d47f641aed077d6</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%2F1545949%2Fe732ac6e-7bda-4001-a9b9-e5b8b1512502.png</url>
      <title>DEV Community: Shuo Wu</title>
      <link>https://dev.to/shuo_wu_00d47f641aed077d6</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shuo_wu_00d47f641aed077d6"/>
    <language>en</language>
    <item>
      <title>I Built an AI Reading Companion with Tree-Structured Conversations</title>
      <dc:creator>Shuo Wu</dc:creator>
      <pubDate>Wed, 24 Jun 2026 01:51:13 +0000</pubDate>
      <link>https://dev.to/shuo_wu_00d47f641aed077d6/i-built-an-ai-reading-companion-with-tree-structured-conversations-3n4i</link>
      <guid>https://dev.to/shuo_wu_00d47f641aed077d6/i-built-an-ai-reading-companion-with-tree-structured-conversations-3n4i</guid>
      <description>&lt;p&gt;&lt;strong&gt;AI makes you productive where you already understand. It confuses you where you don't.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've been reading non-fiction with AI assistants for a while, and I kept hitting the same wall: 30 messages into a conversation about a dense book chapter, the AI starts losing the thread. I'd branch into a tangent — "how does this connect to what Kahneman said about System 1?" — and suddenly the entire chat context is polluted. No way to get back to where I was.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://github.com/shuowu/pi-tree" rel="noopener noreferrer"&gt;&lt;strong&gt;pi-tree&lt;/strong&gt;&lt;/a&gt; — a self-hosted AI reading companion where the conversation &lt;em&gt;is&lt;/em&gt; the reading experience. The key insight: &lt;strong&gt;conversations should be trees, not threads.&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm5y9js99d20xhnkqjx0l.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm5y9js99d20xhnkqjx0l.gif" alt="Router demo — natural language navigation across sources" width="600" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Trees?
&lt;/h2&gt;

&lt;p&gt;When you think through complex material, your mind doesn't work linearly. You branch — &lt;em&gt;"wait, how does this relate to X?"&lt;/em&gt; — explore for a bit, then come back. But every AI chat tool forces you into a flat thread where everything piles up.&lt;/p&gt;

&lt;p&gt;Tree-structured conversations fix this at the architecture level:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Focused context&lt;/strong&gt; — Each branch carries only its path from root to current node. Less noise → more accurate responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token savings&lt;/strong&gt; — A 50-message linear chat sends all 50 every turn. A tree with 5 branches of 10 sends only ~10. Lower cost, faster responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less hallucination&lt;/strong&gt; — Context pollution is a primary cause of hallucination in long conversations. Isolated branches keep the model grounded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's what a reading session looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📖 Reading: Thinking, Fast and Slow (Kahneman)

Root
├── What is System 1 vs System 2?
│   ├── How does this relate to cognitive biases?
│   │   └── Anchoring bias deep-dive
│   └── Real-world examples in decision making
├── Chapter 3: The Lazy Controller
│   └── Why do we avoid effortful thinking?
└── Comparison with Nassim Taleb's ideas
    ├── Black Swan connection
    └── Antifragility and heuristics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's the actual UI — tree sidebar on the left, conversation in the center, table of contents on the right:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F82q98901vazo0quu6t0a.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F82q98901vazo0quu6t0a.png" alt="Book reading session — tree navigation, AI response, chapter TOC" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Agentic, Not RAG
&lt;/h2&gt;

&lt;p&gt;Most "chat with your documents" tools use RAG — chunk your content into embeddings, then retrieve what &lt;em&gt;seems&lt;/em&gt; relevant. The problem: retrieval is approximate. The AI gets semantically similar chunks, not necessarily the &lt;em&gt;right&lt;/em&gt; context.&lt;/p&gt;

&lt;p&gt;Pi-tree takes an agentic approach: the AI has &lt;strong&gt;tools&lt;/strong&gt; that give it precise, on-demand access to your content — more like &lt;code&gt;grep&lt;/code&gt; than vector search. It can look up a specific chapter, fetch a paper's methodology section, or scan today's RSS feeds. The context is exact, structural, and requested when needed — not pre-computed and hoped for.&lt;/p&gt;

&lt;p&gt;Each source type gets purpose-built tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Books&lt;/strong&gt; → &lt;code&gt;process_book&lt;/code&gt; parses EPUB/MOBI/PDF, extracts chapter structure, builds a navigable outline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;News feeds&lt;/strong&gt; → &lt;code&gt;get_latest_rss&lt;/code&gt;, &lt;code&gt;search_rss&lt;/code&gt; crawl your feeds, find trends across sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Papers&lt;/strong&gt; → &lt;code&gt;search_papers&lt;/code&gt;, &lt;code&gt;get_paper_info&lt;/code&gt; query arXiv, fetch and contextualize research&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;YouTube&lt;/strong&gt; → &lt;code&gt;get_youtube_transcript&lt;/code&gt; extracts transcripts for segment-level discussion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI's behavior is then shaped by &lt;strong&gt;skills&lt;/strong&gt; — markdown instruction files that define &lt;em&gt;how&lt;/em&gt; to read, not just what to retrieve.&lt;/p&gt;

&lt;p&gt;Here's a news session — the AI scanned RSS feeds and produced a digest with trends:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7jonywvahsts9zn36gii.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7jonywvahsts9zn36gii.png" alt="News session — AI-powered RSS digest with feed categories" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plugin System
&lt;/h2&gt;

&lt;p&gt;Everything is customizable at three levels:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Skills (Markdown files)&lt;/strong&gt; — Change how the AI reads by editing a &lt;code&gt;.md&lt;/code&gt; file. No code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Session Profiles (YAML)&lt;/strong&gt; — Map source types to different skills, extensions, and models:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;book.reading&lt;/span&gt;
&lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;interactive-reading&lt;/span&gt;
&lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;book&lt;/span&gt;
&lt;span class="na"&gt;exclude_tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Full Plugins (TypeScript)&lt;/strong&gt; — Build new source types with the plugin SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;definePiTreeExtension&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pi-tree/plugin-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;definePiTreeExtension&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my_custom_tool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Does something useful&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sourceId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// your logic here&lt;/span&gt;
    &lt;span class="p"&gt;}&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;There's also an &lt;strong&gt;MCP bridge&lt;/strong&gt; — connect external MCP servers (web search, academic databases, translation APIs) by dropping a JSON config file. Same format as Claude Desktop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start (Docker)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env   &lt;span class="c"&gt;# add your API key&lt;/span&gt;

docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; pi-tree &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env-file&lt;/span&gt; .env &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 3847:3847 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; ~/.local/share/pi-tree:/data &lt;span class="se"&gt;\&lt;/span&gt;
  ghcr.io/shuowu/pi-tree:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;a href="http://localhost:3847" rel="noopener noreferrer"&gt;http://localhost:3847&lt;/a&gt;. That's it.&lt;/p&gt;

&lt;p&gt;Works with any OpenAI-compatible API — cloud providers (DeepSeek, Gemini, Claude, OpenAI) or fully offline with Ollama / LM Studio. Reading doesn't need frontier models — a 12B parameter model works well.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Compares
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Pi-tree&lt;/th&gt;
&lt;th&gt;ChatGPT / Claude&lt;/th&gt;
&lt;th&gt;NotebookLM&lt;/th&gt;
&lt;th&gt;Obsidian + AI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Comprehension &amp;amp; exploration&lt;/td&gt;
&lt;td&gt;General-purpose Q&amp;amp;A&lt;/td&gt;
&lt;td&gt;Document Q&amp;amp;A&lt;/td&gt;
&lt;td&gt;Note-taking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Conversations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🌳 Tree — branch, explore, return&lt;/td&gt;
&lt;td&gt;Linear chat&lt;/td&gt;
&lt;td&gt;Linear chat&lt;/td&gt;
&lt;td&gt;Linear chat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI approach&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agentic — tools &amp;amp; skills over local data&lt;/td&gt;
&lt;td&gt;Prompt + context window&lt;/td&gt;
&lt;td&gt;RAG over uploads&lt;/td&gt;
&lt;td&gt;Plugins over local vault&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sources&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Books, papers, news feeds, YouTube&lt;/td&gt;
&lt;td&gt;File uploads, web&lt;/td&gt;
&lt;td&gt;Multi-doc notebooks&lt;/td&gt;
&lt;td&gt;Markdown vault&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Skills, plugins, MCP bridge&lt;/td&gt;
&lt;td&gt;GPTs (cloud-hosted)&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Community plugins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Model choice&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;BYOK — any provider or local&lt;/td&gt;
&lt;td&gt;Vendor-locked&lt;/td&gt;
&lt;td&gt;Google only&lt;/td&gt;
&lt;td&gt;Plugin-dependent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Local-first, self-hosted&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;Local&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Who Is This For?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nonfiction readers&lt;/strong&gt; — you're reading a dense chapter and AI summaries skip the part you actually don't understand. Pi-tree stays in that gap with you until you do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Researchers &amp;amp; students&lt;/strong&gt; — you're outside your subfield and every paper assumes background you lack. Branch into what you don't know, then return to the argument.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;News followers&lt;/strong&gt; — you read the headline but can't evaluate the claim. Turn feeds into conversations where you build context over time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developers&lt;/strong&gt; — you're in an unfamiliar domain. Build custom plugins to explore anything conversationally.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;🌳 &lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/shuowu/pi-tree" rel="noopener noreferrer"&gt;github.com/shuowu/pi-tree&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📖 &lt;strong&gt;Docs&lt;/strong&gt;: &lt;a href="https://shuowu.github.io/pi-tree/" rel="noopener noreferrer"&gt;shuowu.github.io/pi-tree&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Plugin guide&lt;/strong&gt;: &lt;a href="https://shuowu.github.io/pi-tree/docs/examples" rel="noopener noreferrer"&gt;Building extensions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📸 &lt;strong&gt;Feature tour&lt;/strong&gt;: &lt;a href="https://shuowu.github.io/pi-tree/docs/features" rel="noopener noreferrer"&gt;Screenshots &amp;amp; demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;License:&lt;/strong&gt; AGPL-3.0 — fully open source.&lt;/p&gt;

&lt;p&gt;I'd love feedback on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the tree-structured approach resonate with how you read/research?&lt;/li&gt;
&lt;li&gt;What source types would you want beyond books, news, papers, and YouTube?&lt;/li&gt;
&lt;li&gt;If you self-host LLMs, what models are working well for reading tasks?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Built on the &lt;a href="https://pi.dev/docs/latest/sdk" rel="noopener noreferrer"&gt;Pi SDK&lt;/a&gt; for tree-structured agent sessions.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>ai</category>
      <category>opensource</category>
      <category>reading</category>
    </item>
  </channel>
</rss>
