<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://mattstockton.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mattstockton.com/" rel="alternate" type="text/html" /><updated>2026-08-10T14:51:03+00:00</updated><id>https://mattstockton.com/feed.xml</id><title type="html">Matt Stockton</title><subtitle>Writing about software development, applied AI, and machine learning.</subtitle><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><entry><title type="html">Five Lessons from Putting AI Into Research Teams</title><link href="https://mattstockton.com/2026/07/30/five-lessons-from-putting-ai-into-research-teams.html" rel="alternate" type="text/html" title="Five Lessons from Putting AI Into Research Teams" /><published>2026-07-30T00:00:00+00:00</published><updated>2026-07-30T00:00:00+00:00</updated><id>https://mattstockton.com/2026/07/30/five-lessons-from-putting-ai-into-research-teams</id><content type="html" xml:base="https://mattstockton.com/2026/07/30/five-lessons-from-putting-ai-into-research-teams.html"><![CDATA[<p>Last month I gave a talk to a private working group of finance professionals, a couple dozen people on the call from a mix of firms. The topic was using AI in investment research. I based the talk on tools I’ve built and conversations with teams across the industry. Thirteen lessons prepared for an hour, questions running throughout, and we got through seven.</p>

<p>I built the talk as <a href="/standalone/ai-in-research-teams.html">a single interactive page</a> instead of a slide deck, with a figure you can click through for each lesson. It’s still up, and it’s the fuller version of everything below.</p>

<p><a href="/standalone/ai-in-research-teams.html"><img src="/docs/assets/images/ai-in-research-teams/guide-top.png" alt="AI in Research Teams: Lessons from the Field - the interactive page I built for the talk" /></a></p>

<p>These five are the ones I’d keep if I had twenty minutes instead of an hour. They all sit in the same gap: a tool can work and still not get used. That’s where I’ve seen this work stall, and it’s where most of the questions in the room went.</p>

<h2 id="tools-that-add-work-dont-get-used">Tools that add work don’t get used</h2>

<p>It’s simple math. The time a tool saves has to beat the time it adds in reading, checking, and dealing with what it produces.</p>

<p>A report with everything in it still has to be read. If the output sits on top of the existing process instead of replacing part of it, the analyst has more work than before - and the tool sits idle. It passes the demo, everyone agrees it’s impressive, and three weeks later nobody has opened it. Surfacing too much does the same thing: a digest that flags forty items stops getting read by week three.</p>

<p>So ask two questions. Before you build or buy: after this exists, does the person do less total work, or more? And a month into any pilot: what did you stop doing because of it? If the answer is nothing, it isn’t saving time yet.</p>

<h2 id="librarian-not-analyst">Librarian, not analyst</h2>

<p>Research teams will use AI to gather and organize information. They won’t use it to form judgments for them, and I think they’re right about that.</p>

<p>Analysts don’t want a model shaping their view before they’ve formed their own, even when the model happens to be right. The independent view is what the firm gets paid for. Models handle the facts - company history, competitive landscape, what management has said and done over time. People handle the analysis and the forecasting.</p>

<p>One thing follows from that: start from the analyst’s own notes or draft instead of a blank page. You keep their voice and their framing, and the tool fills in what they missed. And when a tool does get rejected, check whether it crossed into judgment before assuming the team doesn’t get it.</p>

<h2 id="automate-where-the-gathering-is-expensive-and-the-assembly-is-cheap">Automate where the gathering is expensive and the assembly is cheap</h2>

<p>Think of a research task as gathering plus assembly. Pulling filings, transcripts, old notes, and comparables into one place is what these tools are good at, and it’s often the bulk of the hours. Which of your team’s recurring tasks are an hour of collecting and fifteen minutes of putting it together? Automate those first.</p>

<p>The ratio also tells you what to skip. Ten minutes of collecting and an hour of thinking doesn’t leave much for these tools to take off your plate. Teams instinctively want to start with the painful thinking-heavy tasks. Don’t.</p>

<p>The best candidates sit at the far end - checks so gathering-heavy that nobody would do them by hand. Take one claim from an earnings call, say that pricing is holding up across the industry, and check it against what every competitor said that quarter. Or diff this year’s 10-K against last year’s, footnote by footnote, and flag what quietly changed. These weren’t realistic before, and there’s no manual version to compare against, so you’re adding coverage instead of speeding something up.</p>

<p>That’s also the version I’d take to leadership. If early-stage research takes half the time, those hours go to looking at more names.</p>

<h2 id="juniors-and-seniors-have-opposite-problems">Juniors and seniors have opposite problems</h2>

<p>Junior analysts still need to build pattern recognition by reading filings themselves, and a tool that does the reading for them takes away the reps that build it. Seniors have the opposite issue - they evaluate every new tool through decades of existing workflow, so it has to be clearly better than what they already do to earn a slot.</p>

<p>Teams also split into two working styles. Some people form their own view first and use AI to check it afterward. Others work with it from the start. Those habits show up early and they don’t really change, so build tools either group can use their own way.</p>

<p>The cheapest thing you can do is add one standing question to the weekly meeting: what’s the most useful thing you got AI to do this week? That’s how you find the people already doing it, and they’re who should teach the next session.</p>

<h2 id="how-would-we-know-if-it-got-worse">“How would we know if it got worse?”</h2>

<p>Good output today doesn’t tell you much about three months from now. Providers ship updates that change model behavior, sometimes without a version bump, and a workflow you depend on can degrade without anything visibly breaking. These are non-deterministic machines, and for anyone who has run production systems that’s a legitimate concern.</p>

<p>So set up a standing check. Keep a fixed set of tasks where you already know what a good answer looks like, and re-run them on a schedule and after every change to the model, the vendor, or the prompts. The easiest place to get that set is work the team has already done, where the answers are settled. For a research workflow that might be questions about past quarters that everyone on the desk would answer the same way.</p>

<p>Scoring depends on the task. Where there’s a clear right answer, code can check it. Where the output is more of a judgment call, grade it against a written standard, either with a second model or with a person going through a handful of outputs every Friday. Any of these work, as long as they’re on a schedule. Checking only when someone feels suspicious is how drift gets missed.</p>

<p>Ask your vendors the same question, and put your skeptics on it. The person most worried about drift is asking the right question, so hand them the test set.</p>

<h2 id="an-aside-how-i-built-the-page">An aside: how I built the page</h2>

<div class="notice--info">

  <p><strong>A detour from the lessons.</strong> This part is about the format, not the research work.</p>

  <p>I didn’t make slides for this talk. The whole thing is one HTML file. It opens in a browser, works on a phone, and I can email it to someone.</p>

  <p>As a slide, the map below would be a picture I talk over, and it’s useless to anyone who wasn’t on the call. On the page you click a task and get my verdict and the reason for it. The quiz makes you sort tasks yourself before it shows you my answer. The test-set table runs and fails a question in front of you. All of that works the same whether I’m presenting it or you turned it up a month later.</p>

  <p><a href="/standalone/ai-in-research-teams.html"><img src="/docs/assets/images/ai-in-research-teams/quadrant-figure.png" alt="The quadrant map from lesson four, plotting seven research tasks by what the gathering costs and how much judgment the assembly takes" /></a></p>

  <p>How it got built:</p>

  <ol>
    <li><strong>Start from what exists.</strong> My own notes, things I’d already published, a podcast transcript. I pointed a model at those files instead of describing them from memory.</li>
    <li><strong>Write the outline as its own document.</strong> Each lesson as a claim, the reasoning, what to do about it, rough timings. Most of the thinking happened here, in a plain markdown file.</li>
    <li><strong>Describe the audience and the job.</strong> Who’s in the room, how long I have, what they should walk away with.</li>
    <li><strong>Let it draft the page.</strong> Content, layout, and the interactive parts in one file. Each figure started as a sentence or two from me, like “six research tasks, one at a time, reader picks hand-it-to-the-model or keep-it-with-the-person, then show my verdict and a one-line reason.”</li>
    <li><strong>Red-pen it.</strong> Read the draft like an editor, say specifically what’s wrong and why, feed it back. Voice took the most rounds.</li>
  </ol>

  <p>It’s about 1,500 lines of HTML and I’ve read maybe thirty of them. I couldn’t have written it by hand and didn’t need to. The work was describing what each piece should show and how someone moves through it.</p>

  <p>Most people I talk to haven’t tried getting a model to build something like this. Next time you’d make a deck for something people are supposed to poke at on their own, ask for a page instead and see how it goes.</p>

</div>

<h2 id="what-it-comes-down-to">What it comes down to</h2>

<p>The models are already good enough for most of what a research team needs. The work is picking the right tasks, keeping judgment with the people who get paid for it, and making the output checkable. That part doesn’t get easier when the next model ships.</p>

<p>So start with one named workflow instead of a firm-wide platform: reviewing earnings transcripts, prepping for a management meeting, refreshing a comp table. Have one motivated person get it working hands-on in a tool that can reach the actual files, then write down what worked so the next person doesn’t start over. And check where your data actually lives before you build anything on top of it, because no purchase fixes that part. I covered the path from one working version to something the whole firm uses in <a href="/2026/07/07/building-the-multiplayer-institutional-brain.html">Building the Multiplayer Institutional Brain</a>.</p>

<p>If you’re doing this inside a research team, I’d like to hear which of these don’t match what you’re seeing. The adoption ones are where I’d expect the most variation from one firm to the next.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="AI Strategy &amp; Leadership" /><category term="ai-adoption" /><category term="investment-research" /><category term="research-workflows" /><category term="evals" /><category term="ai-tools" /><summary type="html"><![CDATA[Which tasks to automate, where analysts push back, and how to tell if a workflow is quietly getting worse - five lessons from a talk I gave last month on getting AI into research workflows.]]></summary></entry><entry><title type="html">How I Use Modal</title><link href="https://mattstockton.com/2026/07/12/how-i-use-modal.html" rel="alternate" type="text/html" title="How I Use Modal" /><published>2026-07-12T00:00:00+00:00</published><updated>2026-07-12T00:00:00+00:00</updated><id>https://mattstockton.com/2026/07/12/how-i-use-modal</id><content type="html" xml:base="https://mattstockton.com/2026/07/12/how-i-use-modal.html"><![CDATA[<p>I’ve been using Modal in my consulting work for a while, and it’s become my favorite piece of infrastructure. It keeps the infrastructure code small and lets me focus on the application. After listening to a recent <a href="https://www.latent.space/p/modal2026">Latent Space episode with Modal’s CTO</a>, I realized I’d never written down how I use it.</p>

<p>For those unfamiliar: <a href="https://modal.com">Modal</a> is a serverless platform for Python. You decorate ordinary functions with infrastructure configuration, define your dependencies in a Dockerfile or declaratively in Python, and Modal runs the functions in its cloud. Scheduling, scaling, HTTPS routing, and log capture are all handled for you.</p>

<p>The same problems come up often: Python data pipelines, a warehouse, internal tools, and AI jobs. Modal can handle individual pieces or most of the cloud layer. Below are two generalized patterns from that work:</p>

<ul>
  <li><strong>A scheduled ingestion service.</strong> Every morning it pulls report data from a third-party vendor’s API and lands it in Snowflake. It isn’t the only feed into the warehouse, but the others load outside Modal, so I’m leaving them out. On Modal this is one function, about 60 lines of infrastructure code total.</li>
  <li><strong>An internal data platform.</strong> A Streamlit web portal with dashboards built on Snowflake data, AI agents that generate long-form reports as background jobs, and an MCP server that exposes the same data tools to Claude and ChatGPT clients. Five Modal functions plus on-demand sandboxes, all built from one container image.</li>
</ul>

<p>I don’t run Kubernetes or Terraform for any of this. The only consoles I touch are Modal’s dashboard and Snowflake. Each of these deploys as a dev and a prod copy from the same file, using an environment suffix on every named resource.</p>

<p>One thing to know up front: this isn’t Modal’s main use case. Modal is best known for GPU workloads (model inference, fine-tuning, large parallel batch jobs) and for sandboxed code execution inside AI agents, which is most of what that podcast episode covers. I’m using it as general-purpose infrastructure: cron jobs, web hosting, background work, storage, networking. It handles that kind of work really well too.</p>

<h2 id="the-features">The features</h2>

<h3 id="functions">Functions</h3>

<p>Everything on Modal is a function. Each one declares its own resources (CPU, memory, timeout, concurrency) as decorator arguments, and can be triggered by a cron schedule, an HTTP request, or a call from other Python code. All the functions in a project share one container image, which Modal builds from the repo’s <code class="language-plaintext highlighter-rouge">Dockerfile</code>. The infrastructure configuration lives in the same Python files as the application code, in the same git history.</p>

<h3 id="cron-schedules">Cron schedules</h3>

<p>The entire ingestion service is a single function with a schedule attached:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">function</span><span class="p">(</span>
    <span class="n">secrets</span><span class="o">=</span><span class="p">[</span><span class="n">modal</span><span class="p">.</span><span class="n">Secret</span><span class="p">.</span><span class="n">from_name</span><span class="p">(</span><span class="n">SECRET_NAME</span><span class="p">)],</span>
    <span class="n">schedule</span><span class="o">=</span><span class="n">modal</span><span class="p">.</span><span class="n">Cron</span><span class="p">(</span><span class="s">"0 6 * * *"</span><span class="p">,</span> <span class="n">timezone</span><span class="o">=</span><span class="s">"America/New_York"</span><span class="p">),</span>
    <span class="n">proxy</span><span class="o">=</span><span class="n">modal</span><span class="p">.</span><span class="n">Proxy</span><span class="p">.</span><span class="n">from_name</span><span class="p">(</span><span class="s">"egress-proxy"</span><span class="p">),</span>
<span class="p">)</span>
<span class="k">def</span> <span class="nf">pull_reports_scheduled</span><span class="p">():</span>
    <span class="kn">from</span> <span class="nn">myproject.pipeline</span> <span class="kn">import</span> <span class="n">pull_reports</span>
    <span class="k">return</span> <span class="n">pull_reports</span><span class="p">()</span>
</code></pre></div></div>

<p>Modal runs it every morning, and the logs and run history show up in the dashboard. When I need a backfill, I trigger the same function manually with one CLI command. This job used to be a GitHub Actions cron, and Modal has been easier to live with: the job runs in the project’s own container image instead of a runner that gets set up from scratch on every run, and it gets the static egress IP described below.</p>

<h3 id="secrets">Secrets</h3>

<p>A Modal secret is a named bundle of key-value pairs. You create it in Modal’s dashboard and it gets injected into the container as environment variables at runtime. Each project has one secret per environment holding warehouse credentials, vendor API keys, LLM provider keys, and OAuth config. Application code just reads <code class="language-plaintext highlighter-rouge">os.environ</code>, and it works the same on my laptop (where the variables come from a git-ignored <code class="language-plaintext highlighter-rouge">.env</code> file) as it does in the cloud. Nothing sensitive lands in the repository.</p>

<h3 id="volumes">Volumes</h3>

<p>Volumes are network filesystems that mount into containers and survive between runs. I keep all the data platform’s non-warehouse state on them: a SQLite database for job tracking, parquet snapshots of every dashboard dataset, fetched source material for the report jobs, generated reports, self-contained HTML tools, and OAuth token state. The one rule is that syncing is explicit: writers call <code class="language-plaintext highlighter-rouge">commit()</code> when they’re done, and readers call <code class="language-plaintext highlighter-rouge">reload()</code> before reading. In exchange you get durable storage without setting up a database or object store.</p>

<h3 id="static-ips">Static IPs</h3>

<p>Serverless containers normally get arbitrary outbound IPs, which breaks anything that enforces an IP allowlist. Attaching <code class="language-plaintext highlighter-rouge">proxy=modal.Proxy.from_name("egress-proxy")</code> to a function routes all its outbound traffic through a managed tunnel with one static IP. Everything in this post shares a single proxy, so the warehouse and the vendors only have to allowlist one address. This lets Modal work with strict network policies.</p>

<h3 id="web-endpoints">Web endpoints</h3>

<p>Modal can give a function a stable HTTPS URL in two ways, and I use both:</p>

<ul>
  <li><strong><code class="language-plaintext highlighter-rouge">@modal.web_server</code></strong> wraps any process listening on a port. The Streamlit portal runs this way. The function starts Streamlit as a subprocess, and Modal routes HTTPS traffic to it (including the WebSockets Streamlit depends on), keeps a container warm while sessions are active, and scales to zero when idle.</li>
  <li><strong><code class="language-plaintext highlighter-rouge">@modal.asgi_app</code></strong> serves an ASGI application directly. The MCP server (a FastMCP app behind an OAuth flow) and a small sidecar that serves HTML tools both run this way.</li>
</ul>

<p>The portal is just Python running in a container, so it isn’t limited to showing precomputed data. While someone is using it, it can make live API calls to whatever it needs (LLM APIs, the warehouse, vendor services), all through the same static-IP proxy. The morning ingestion is batch, but the data platform isn’t.</p>

<p>A note for Snowflake shops: Snowflake owns Streamlit, and you can host Streamlit apps directly inside Snowflake. I run them on Modal instead, mostly for cost. An app hosted in Snowflake keeps a warehouse running whenever someone is using it, which adds up fast for an internal tool that’s open all day. The parquet cache on the volumes is the other half of the same decision: most of the dashboard data changes once a day, so the portal reads parquet files from a volume and only queries the warehouse when a cache is stale or missing. It’s a slightly odd setup, but reads are faster, the warehouse spends most of the day suspended, and the Snowflake bill stays small.</p>

<p>About those HTML tools: some internal tools are easiest to build as a single self-contained HTML file, with the JavaScript and CSS inline, rather than as part of the Streamlit app. The sidecar is how those stay behind the platform’s login: the files live on a volume, and the portal hands a logged-in user a short-lived signed link that opens the tool in its own browser tab. It’s an easy way to slot static HTML tools into the platform without separate hosting or a second login.</p>

<p>Each endpoint has its own auth: OIDC browser login for the portal, OAuth for MCP clients, HMAC-signed URLs for the tools sidecar. “Serverless” on Modal covers full interactive web applications, with login flows, WebSockets, and long-lived sessions.</p>

<h3 id="calling-functions-from-code">Calling functions from code</h3>

<p>Any deployed function can be called from other Python code by name. I use this for two things.</p>

<p>The first is synchronous, as a deploy hook. My deploy command runs <code class="language-plaintext highlighter-rouge">modal deploy</code> and then immediately calls <code class="language-plaintext highlighter-rouge">Function.from_name(APP_NAME, "warm_cache").remote()</code>, which pulls every dashboard dataset from Snowflake into parquet files on the cache volume. Every deploy ships with a fresh cache, and there’s no schedule to maintain.</p>

<p>The second is asynchronous, as a job queue. Users submit AI report-generation jobs that run for many minutes, way too long for a web request. The web app fires them off and polls:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># submit
</span><span class="n">call</span> <span class="o">=</span> <span class="n">modal</span><span class="p">.</span><span class="n">Function</span><span class="p">.</span><span class="n">from_name</span><span class="p">(</span><span class="n">APP_NAME</span><span class="p">,</span> <span class="s">"run_agent_report"</span><span class="p">).</span><span class="n">spawn</span><span class="p">(</span><span class="n">params</span><span class="o">=</span><span class="p">...)</span>
<span class="n">db</span><span class="p">.</span><span class="n">record_job</span><span class="p">(</span><span class="n">call</span><span class="p">.</span><span class="n">object_id</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="s">"running"</span><span class="p">)</span>

<span class="c1"># poll, on each page refresh (call_id comes from the db)
</span><span class="k">try</span><span class="p">:</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">modal</span><span class="p">.</span><span class="n">FunctionCall</span><span class="p">.</span><span class="n">from_id</span><span class="p">(</span><span class="n">call_id</span><span class="p">).</span><span class="n">get</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="k">except</span> <span class="nb">TimeoutError</span><span class="p">:</span>
    <span class="k">pass</span>  <span class="c1"># still running
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">spawn()</code> returns a durable call ID immediately. <code class="language-plaintext highlighter-rouge">get(timeout=0)</code> raises while the job is still running and returns the result when it finishes. Combined with a SQLite table on a volume, that’s the platform’s entire background-job system. I didn’t have to set up a broker or a worker fleet.</p>

<h3 id="sandboxes">Sandboxes</h3>

<p>Sandboxes are containers you create on the fly from code, without deploying anything first.</p>

<p>Here’s how I use them. My project CLI has commands that run AI agents, and some of them run for half an hour. This is where the more experimental work lives: agents I’m still iterating on that haven’t been integrated into the core code yet, and bespoke jobs that don’t need a place in the web UI. Run locally, they die if the laptop sleeps. So the CLI has a <code class="language-plaintext highlighter-rouge">--remote</code> flag: instead of running the agent on my machine, it creates a Modal sandbox from the same Dockerfile image, runs the exact same command inside it, and streams the output back to my terminal so it looks like a local run. When the job finishes, the CLI copies the result files down to my machine and shuts the sandbox down.</p>

<p>Unlike the deployed functions everywhere else in this post, nothing here is registered ahead of time. A sandbox runs whatever command you give it, so a new CLI command needs nothing deployed or registered on Modal’s side before it can run remotely.</p>

<h2 id="how-it-fits-together">How it fits together</h2>

<p><img src="/docs/assets/images/how-i-use-modal/modal-architecture.png" alt="Diagram of the two patterns: a cron-triggered ingestion function, and an internal platform of five Modal functions plus sandboxes sharing Modal volumes, with egress to Snowflake, vendor APIs, and LLM APIs through one static-IP proxy" /></p>

<p>Secrets and the shared image apply to every function. Volumes and the proxy only attach where they’re needed. The warehouse’s other data feeds load outside Modal and aren’t shown.</p>

<h2 id="when-this-makes-sense">When this makes sense</h2>

<p>Across these patterns, Modal covers scheduled batch jobs, an interactive web application, API endpoints with auth, background AI jobs, persistent storage, static-IP networking, and one-off remote runs. All of it is decorators and name lookups in ordinary Python repositories. No single project needs the whole list, but the same pieces keep coming up because the problem space is the same. There’s also a lot of Modal I don’t use, or don’t use yet. I don’t need GPUs because inference happens through LLM provider APIs. Modal has built-in queues and container fan-out that I could be using for background jobs, but so far a thread pool and a SQLite table on a volume have been enough. That’s how the platform works in practice: you pull in the pieces you need, everything else is Python you write yourself, and the built-in versions are there if you outgrow your own.</p>

<p>On cost: you can start for free. Modal’s free plan includes $30 a month in compute credit, which is enough to experiment and get a feel for the platform. You could genuinely run some small infrastructure without paying anything. The paid plan jumps to $250 a month, and a few features in this post are gated behind it, including the static IP proxy and unlimited cron schedules (the free plan caps you at five). So in practice, if Modal works for you, expect to pay $250 a month. That includes $100 a month in compute credit, and if you design your system prudently, that credit gets you really far.</p>

<p>If you’re building Python systems with a data warehouse behind them, this covers most of what you need from an infrastructure platform, and one person or a small team can operate all of it. The reason I like Modal comes down to simplicity: the infrastructure is just code in the same repo as the application, so I’m never really working outside the project. It’s well documented, the defaults are pragmatic, and most of the decisions infrastructure usually forces on you are already made. I get a lot done without doing a lot of work. Start with something small, like a cron job you’re currently running on GitHub Actions, and see how it feels.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="Software Engineering" /><category term="modal" /><category term="infrastructure" /><category term="python" /><category term="serverless" /><category term="data-engineering" /><summary type="html"><![CDATA[A tour of two practical Modal deployment patterns: cron jobs, secrets, volumes, static IPs, web apps, background AI jobs, and sandboxes, all in plain Python.]]></summary></entry><entry><title type="html">Building the Multiplayer Institutional Brain</title><link href="https://mattstockton.com/2026/07/07/building-the-multiplayer-institutional-brain.html" rel="alternate" type="text/html" title="Building the Multiplayer Institutional Brain" /><published>2026-07-07T00:00:00+00:00</published><updated>2026-07-07T00:00:00+00:00</updated><id>https://mattstockton.com/2026/07/07/building-the-multiplayer-institutional-brain</id><content type="html" xml:base="https://mattstockton.com/2026/07/07/building-the-multiplayer-institutional-brain.html"><![CDATA[<p>I recently joined <a href="https://x.com/khemaridh">Khe</a> and <a href="https://x.com/FundamentEdge">Brett</a> on the <a href="https://www.fundamentedge.com/invest-with-ai-episodes/04">Invest with AI</a> podcast to talk about the transition from individual AI experimentation to a shared “multiplayer” institutional brain. Most of our conversation was about process and communication, because in my experience that’s where firms get stuck - more than on the technology itself.</p>

<p><img src="/docs/assets/images/invest-with-ai/institutional_brain.jpg" alt="Building the multiplayer institutional brain: scaling AI from individual to institution" /></p>

<p>Here are the core strategies from our discussion:</p>

<h2 id="1-start-with-the-job-to-be-done">1. Start with the “Job to Be Done”</h2>

<p>Identify specific, named workflows - reviewing earnings transcripts, summarizing SEC filings - and systematize them one at a time. Design each one around your firm’s investment thesis and the specific lens you use to evaluate data. That’s how context moves out of individual silos and into shared spaces where a model can apply your firm’s approach.</p>

<h2 id="2-use-models-as-thought-partners-to-solve-articulation">2. Use Models as Thought Partners to Solve Articulation</h2>

<p>About 80% of AI engineering is clear communication. Many experts are “intuitive pianists”: they have masterful processes but struggle to write them down coherently. The models themselves are excellent interviewers for extracting that intent. My favorite version of this is to record a rambling voice memo of my thoughts, transcribe it, and ask the model to exhaustively ask me questions until it understands my intent and can turn it into structured instructions.</p>

<h2 id="3-prioritize-local-access-for-deep-experimentation">3. Prioritize Local Access for Deep Experimentation</h2>

<p>To build a firm-wide brain, you first have to prove what works in a single-player environment. Get out of the browser and use harnesses like Codex or Claude Code that have direct access to your local file system. The model can open folders and look through things to find context on its own, which changes how fast you can iterate - I wrote more about this in <a href="/2025/12/29/why-tool-calling-and-file-system-access-matter.html">why tool calling and file system access matter</a>. You’ll eventually move these workflows into a shared, centralized environment, but you can’t prove the process until the tool can see the data you’re working with.</p>

<h2 id="4-adopt-a-hill-climbing-feedback-loop">4. Adopt a “Hill Climbing” Feedback Loop</h2>

<p>Treat development as hill climbing: apply a red pen to the model’s logic and iterate on its errors. The loop I use is to record a specific critique of what was good or bad about a particular output and feed that transcription back into the system to refine the underlying skill. Do this enough times and the model starts to speak your professional language and handle the nuanced calls correctly.</p>

<h2 id="5-build-durable-skills-instead-of-custom-code">5. Build Durable “Skills” Instead of Custom Code</h2>

<p>Build a firm-wide library of “skills”: reusable, English-language recipes for specific tasks. Because they’re written in plain language, they stay durable as you switch between underlying models like GPT or Claude. When a team member finds a recipe that works, it goes into a shared repository so the whole firm benefits.</p>

<h2 id="6-design-for-adaptability-and-the-bitter-lesson">6. Design for Adaptability and the “Bitter Lesson”</h2>

<p>The half-life of an AI technique is short; be prepared to throw away or redo your work as models improve. Build workflows around the underlying intent and logic rather than rigid, over-prescribed instructions. Work built that way can be evolved and repurposed instead of going obsolete every time a new model ships.</p>

<h2 id="7-treat-llms-as-orchestrators">7. Treat LLMs as Orchestrators</h2>

<p>LLMs are one tool in your kit, and they’re often the wrong tool for the job. They’re non-deterministic, which makes them good at judgment and reasoning and unreliable at perfect math or quantitative analysis. Don’t ask an LLM to perform calculations; use it as an orchestrator that triggers deterministic code or specialized tools to handle the numbers. Once a task is proven and repeatable, move it to smaller, cost-optimized models for better efficiency at scale.</p>

<hr />

<p>My advice has been consistent through this entire AI wave: <strong>there are no shortcuts</strong>. The only way to get good at this and understand what works for your lens is to put in the time - it’s <a href="/2026/01/29/what-i-tell-people-getting-started-with-claude-code.html">what I tell everyone getting started</a>. As we said on the podcast, hitting a professional level of fluency usually takes hundreds of hours of hands-on work. The tools will keep shifting; the time you spend in the weeds is what carries over. You have to get in there and find the “aha moments” for yourself.</p>

<p>If you want the full conversation, you can listen to the <a href="https://www.fundamentedge.com/invest-with-ai-episodes/04">complete episode</a> on the Fundament Edge site.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="AI Strategy &amp; Leadership" /><category term="podcasts" /><category term="ai-adoption" /><category term="investment-research" /><category term="skills" /><category term="workflows" /><summary type="html"><![CDATA[I joined Khe and Brett on the Invest with AI podcast to talk about how investment firms move from individual AI experimentation to a shared, firm-wide capability. These are the seven strategies from our conversation.]]></summary></entry><entry><title type="html">There’s More Public Data Than People Exploring It</title><link href="https://mattstockton.com/2026/06/04/theres-more-public-data-than-people-exploring-it.html" rel="alternate" type="text/html" title="There’s More Public Data Than People Exploring It" /><published>2026-06-04T00:00:00+00:00</published><updated>2026-06-04T00:00:00+00:00</updated><id>https://mattstockton.com/2026/06/04/theres-more-public-data-than-people-exploring-it</id><content type="html" xml:base="https://mattstockton.com/2026/06/04/theres-more-public-data-than-people-exploring-it.html"><![CDATA[<p>I recently built <a href="https://wattsopen.com/">WattsOpen</a>, an interactive site about where the US grid has room. It maps the large fossil plants retiring over the next several years, scores those sites on how close they are to existing transmission and gas lines, and digs into interconnection queues, retirement schedules, and the hour-by-hour fuel mix on each grid. Everything on it comes from open federal data, and I made the whole thing with <a href="https://docs.anthropic.com/en/docs/claude-code/overview">Claude Code</a>.</p>

<p><img src="/docs/assets/images/wattsopen/prospect-map-tx.png" alt="Retiring US fossil plants mapped against the high-voltage transmission network on WattsOpen" /></p>

<p>WattsOpen started as a way to test two theses I’ve had for a while. The first is that there’s a huge amount of data out there, structured and unstructured, that’s largely underexplored. People aren’t looking at it, and they’re mostly not trying to see how different datasets connect. <a href="https://fred.stlouisfed.org/">FRED</a> alone has over 800,000 economic time series. The EIA publishes monthly filings on every generator in the country. And honestly, this kind of exploration is one of the things AI is most useful for - understanding what a dataset is, writing the code to process it, figuring out how it relates to other data.</p>

<p>The second thesis is that these tools have gotten incredibly good at creating the right user experience for visualizing information. They can build something interactive that gets you to the signal quickly, and they can do it mostly automatically.</p>

<h2 id="why-the-grid">Why the Grid</h2>

<p>I’ve been curious about how the grid fits into what’s happening in AI right now. Power keeps coming up as the bottleneck for data center construction, and when I started asking basic questions about it - what’s retiring, where does new generation connect, why does it take years - I realized I didn’t really understand anything about how the grid works. I didn’t know what an interconnection queue was or what a balancing authority does.</p>

<p>I could have read explainers, but I learn better by building. The plan was to pull the real data, work through it with Claude Code, and end up with something I could keep using and updating as I learn more. The site is as much a tool for my own learning as it is something to share.</p>

<h2 id="what-wattsopen-is">What WattsOpen Is</h2>

<p>The site tells five short stories on top of the same data:</p>

<ol>
  <li><strong>A co-location atlas</strong> - every US fossil plant of 100 MW or more retiring between 2024 and 2030, scored on distance to high-voltage transmission, distance to interstate gas, site size, and recent utilization. These are sites where grid infrastructure is already in place and about to be freed up.</li>
  <li><strong>A retirement schedule</strong> - a county-by-county map of the roughly 73 GW of fossil capacity scheduled to retire through 2035.</li>
  <li><strong>A headroom time machine</strong> - a replay of ten years of monthly <a href="https://www.eia.gov/electricity/data/eia860m/">EIA-860M</a> filings, showing when retirement plans first appeared in the public record, county by county.</li>
  <li><strong>A queue reality check</strong> - withdrawal rates, time-to-operation, and resource mix for the interconnection queues in nine regions, built on <a href="https://emp.lbl.gov/queues">LBNL’s Queued Up data</a>.</li>
  <li><strong>An hourly fuel-mix clock</strong> - what’s on the wire hour by hour across nine balancing authorities, from EIA-930 data.</li>
</ol>

<div style="display: flex; gap: 10px; align-items: flex-start;">
  <img src="/docs/assets/images/wattsopen/time-machine-map.png" alt="The headroom time machine: county-level retirement filings replayed month by month" style="width: 70%;" />
  <img src="/docs/assets/images/wattsopen/fuel-mix-clock.png" alt="The hourly fuel-mix clock for PJM" style="width: 28%;" />
</div>

<p>The sources are EIA generator and utility filings, hourly grid data from EIA-930, LBNL’s queue research, and HIFLD’s maps of transmission lines and gas pipelines. All of it is free, though for most of the sources I had to sign up for an API key.</p>

<h2 id="how-i-worked">How I Worked</h2>

<p>The first commit was May 16. The site was live about two and a half weeks later - 33 commits across nine days of touching the project, all in spare time.</p>

<p>Claude Code was the thought partner for the whole thing. I used it to understand what the datasets actually are, to build the code that processes them, to figure out how they relate to each other, and to build the visualizations. Before processing a dataset I’d have it explain what I was looking at - who files EIA-860M and why, what “nameplate capacity” means, how LBNL assembles queue data from nine regions that each define project status differently. Then it wrote the pipeline (fetch each source, normalize to Parquet, load into DuckDB, export JSON for the site) and built the site itself in static HTML and D3 with no build step.</p>

<p>The loop was the same every session. Ask what datasets exist for a question I had, fetch one, have Claude explain the columns and how the data gets collected, look at it together, then figure out how it could join to what we already had. The most useful results came from the joins - retirement filings matched to transmission line locations tell you something neither dataset does on its own.</p>

<h2 id="what-i-learned">What I Learned</h2>

<p>My mental model of this space is still crude, but a few things stuck:</p>

<ul>
  <li>About 1.8 TW of nameplate capacity sits in US interconnection queues, which is more than the entire installed generating fleet. Historically most of it never gets built. Across the projects in the data, about 85% never reach commercial operation, and the ones that do typically wait two to five years.</li>
  <li>Meanwhile, fossil plants retire on a published schedule, at sites that are already wired. The median retiring plant in the atlas is a quarter mile from a high-voltage substation and about five miles from an interstate gas pipeline.</li>
  <li>The fuel mix on each grid changes hour by hour. Solar pushes gas off the grid at noon in some markets while coal runs flat through the day in others - patterns that annual averages smooth over.</li>
</ul>

<p><img src="/docs/assets/images/wattsopen/queue-reality.png" alt="Interconnection queue funnel showing share of projects by status per region" /></p>

<p>None of this is news to anyone in the industry, but it was all news to me, and working through the data myself made it stick in a way that reading about it wouldn’t have.</p>

<h2 id="what-this-isnt">What This Isn’t</h2>

<p>I’m sure I got a ton of things wrong here. If you’re an expert in this space, you’ll probably look at WattsOpen and see a naive view of how the grid works, and maybe some things that make no sense at all. Every page on the site has a banner saying it’s a personal learning project, not expert analysis, and I mean that. There’s no parcel-level analysis, no per-RTO transfer rules, and the queue data is an annual snapshot with status definitions that vary by region. None of that made it less useful as a way to dig into the space and learn. Just don’t use it to make siting decisions.</p>

<h2 id="final-thoughts">Final Thoughts</h2>

<p>The grid was the subject here, but the thing I’m most enthused about is the workflow: exploring data in an applied fashion to learn a domain, and ending up with something I can keep using to learn more. The same approach would work on macro series from FRED, SEC filings, court records, FDA databases - any field with a pile of public data behind it. I <a href="/2026/01/10/the-biggest-ai-opportunity-isnt-better-models.html">wrote a few months ago</a> about domain experts being the biggest AI opportunity. This project was sort of the inverse. I had no expertise, and the tools still got me to something I learned a lot from and that might be useful to other people. Someone who knows energy cold could skip the tutorial phase and go a lot further.</p>

<p>If you know this space, I’d like to hear what WattsOpen gets wrong - that’s part of the learning. And I’m curious whether others are doing this kind of applied exploration with public data in their own fields.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="Building with LLMs" /><category term="ai-tools" /><category term="claude-code" /><category term="open-data" /><category term="energy" /><category term="data-visualization" /><summary type="html"><![CDATA[I used Claude Code to connect open federal energy datasets into WattsOpen, an interactive site about where the grid has room. It started as a way to test two theses about AI and public data.]]></summary></entry><entry><title type="html">Automating the Path from Frontier Models to Fine-Tuned Models</title><link href="https://mattstockton.com/2026/03/02/automating-the-path-from-frontier-models-to-fine-tuned-models.html" rel="alternate" type="text/html" title="Automating the Path from Frontier Models to Fine-Tuned Models" /><published>2026-03-02T00:00:00+00:00</published><updated>2026-03-02T00:00:00+00:00</updated><id>https://mattstockton.com/2026/03/02/automating-the-path-from-frontier-models-to-fine-tuned-models</id><content type="html" xml:base="https://mattstockton.com/2026/03/02/automating-the-path-from-frontier-models-to-fine-tuned-models.html"><![CDATA[<p>I saw a post from <a href="https://x.com/virattt/status/2027809465789980896">Virat</a> at <a href="https://x.com/findatasets">findatasets</a> recently about using GPT 5.2 to parse 8-K filings. It works well but it’s expensive at scale. His plan was to accumulate examples and fine-tune an open model to bring cost down. <a href="https://x.com/mstockton/status/2027854211992764430">I replied</a> that this loop - frontier model generates outputs, outputs become training data, training data fine-tunes a cheaper model - could be almost fully automated.</p>

<p>I haven’t done fine-tuning in a while. Frontier models just work for most of what I’ve needed, so I haven’t had a reason to. But Virat’s post got me thinking about this pattern more carefully, and it seems like something worth exploring.</p>

<h2 id="structured-extraction-and-evaluation">Structured Extraction and Evaluation</h2>

<p>The reason this pattern seems especially interesting for structured extraction is that it’s easier to evaluate. If you’re pulling known fields out of semi-structured documents - dates, entities, financial figures - there’s a clearer definition of “correct” than with freeform text. Some checks can be automated (does this parse as a valid date? does this value appear in the source document?), and people can review the rest.</p>

<p>If you’re using a frontier model for extraction at any real volume, you should already be evaluating its outputs - having people review results, label quality, build an evaluation set. That evaluation work produces labeled (input, output) pairs. And if you orchestrate the system correctly, those labeled pairs can double as training data for a cheaper model.</p>

<h2 id="what-the-retraining-loop-would-look-like">What the Retraining Loop Would Look Like</h2>

<p>I think the workflow would look something like this:</p>

<ol>
  <li>
    <p><strong>Run the frontier model on your extraction task.</strong></p>
  </li>
  <li>
    <p><strong>Evaluate outputs.</strong> People review and label results. Automated checks can help with the obvious stuff (schema validation, format checks, cross-referencing source documents). This is ongoing work, not a one-time thing.</p>
  </li>
  <li>
    <p><strong>Evaluated outputs become your training dataset.</strong> Every (input, output) pair that’s been reviewed and labeled goes into your training set.</p>
  </li>
  <li>
    <p><strong>Fine-tune a smaller, cheaper model on this data.</strong> Once you have enough high-quality examples, fine-tune an open model like Llama or Mistral.</p>
  </li>
  <li>
    <p><strong>Evaluate the fine-tuned model out of sample.</strong> Check how it performs on examples it wasn’t trained on. This tells you whether it’s actually good enough to deploy.</p>
  </li>
  <li>
    <p><strong>Deploy the fine-tuned model for bulk traffic.</strong> If it meets your quality bar, route extraction volume through the cheaper model. Use the frontier model as a fallback for cases where the fine-tuned model’s confidence is low. You’d also want a way for people to flag bad outputs, so those can feed back into your training data.</p>
  </li>
  <li>
    <p><strong>Continue accumulating data and periodically retrain.</strong> The frontier model fallback path keeps generating new examples for people to evaluate. Each cycle grows the training set.</p>
  </li>
</ol>

<p>If you set up the right hooks - a pipeline for people to label outputs, a process for checking fine-tuned model performance out of sample, off-ramps for routing traffic to cheaper models - the retraining loop falls out of the orchestration. You’re connecting evaluation work you should already be doing to a fine-tuning pipeline.</p>

<h2 id="this-is-just-mlops">This Is Just MLOps</h2>

<p>The thing that struck me about this pattern is that it’s not new. It’s the same retraining loop that classical ML teams have been running for years. Collect labeled data, train a model, deploy it, monitor performance, collect more data, retrain.</p>

<p>In traditional ML, labeling was always the bottleneck. You’d hire annotators to label documents from scratch, and it was tedious, expensive, and slow.</p>

<p>Now frontier models are good enough that they can do the initial extraction at high quality, and you can use techniques like LLM-as-judge to get reasonable confidence that the outputs are correct. You still need humans in the loop reviewing labels, but you’re spot-checking outputs that are already mostly right rather than creating labels from zero. That makes the human review much less costly, which is a big part of why this pattern feels more viable now than it would have a couple years ago.</p>

<p>I’d imagine teams with classical ML experience have an advantage here. They already know how to build data pipelines, version datasets, run A/B tests between model versions, and monitor for drift. If you’ve ever built a retraining pipeline for a classification model or an NER system, you probably already know most of what this requires.</p>

<h2 id="where-i-think-this-does-and-doesnt-apply">Where I Think This Does and Doesn’t Apply</h2>

<p>I haven’t validated all of this myself, but based on what I’ve read, it seems like the pattern fits well when:</p>

<ul>
  <li>There’s a clear definition of “correct” - structured extraction, classification, entity recognition</li>
  <li>Volume is high enough to justify the investment (thousands of examples)</li>
  <li>The domain is relatively stable - document formats don’t change weekly</li>
  <li>Cost matters at scale - you’re spending real money on frontier model API calls</li>
</ul>

<p>And it probably fits less well when:</p>

<ul>
  <li>Outputs are subjective or hard to evaluate - summarization, creative writing, open-ended Q&amp;A</li>
  <li>The domain shifts frequently, invalidating your training data</li>
  <li>You need the frontier model’s breadth and general reasoning, not narrow pattern-following</li>
  <li>Volume is low - if you’re processing a hundred documents a month, just keep using the frontier model</li>
</ul>

<p>From what I’ve read, fine-tuning starts making sense around a few hundred to a few thousand high-quality examples.</p>

<h2 id="fine-tuning-has-gotten-easier">Fine-Tuning Has Gotten Easier</h2>

<p>The last time I experimented with fine-tuning was through the <a href="https://platform.openai.com/docs/guides/fine-tuning">OpenAI fine-tuning API</a>, and it was mostly hello-world level stuff. I didn’t have a real use case to push it further.</p>

<p>The tooling seems like it’s gotten a lot better since then, and there are more options now. <a href="https://github.com/unslothai/unsloth">Unsloth</a> is one I’ve seen mentioned frequently for running fine-tuning on a single GPU. I have some projects on the horizon where this kind of loop might be worth experimenting with, so I want to spend more time here.</p>

<h2 id="final-thoughts">Final Thoughts</h2>

<p>The human evaluation part of this doesn’t go away, and I don’t want to downplay that. Someone needs to define what “correct” means, review outputs, and make judgment calls about when the fine-tuned model is good enough. But the orchestration around it - the pipeline from evaluated outputs to training data to fine-tuned model to deployment with off-ramps - that part seems like it can be set up once and mostly run itself.</p>

<p>I’m curious whether teams are actually doing this today, and what their experience has been. If you’re running frontier models on structured extraction at volume and you’re already evaluating outputs, it seems like you’re close to having what you need. I want to spend more time exploring this and see what it takes to get a working version of this loop running end to end.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="Software Engineering" /><category term="ai-tools" /><category term="llm" /><category term="fine-tuning" /><category term="mlops" /><category term="software-engineering" /><summary type="html"><![CDATA[A tweet about fine-tuning on frontier model outputs got me thinking about how much of that loop could be automated.]]></summary></entry><entry><title type="html">What Is An Agent?</title><link href="https://mattstockton.com/2026/02/21/what-is-an-agent.html" rel="alternate" type="text/html" title="What Is An Agent?" /><published>2026-02-21T00:00:00+00:00</published><updated>2026-02-21T00:00:00+00:00</updated><id>https://mattstockton.com/2026/02/21/what-is-an-agent</id><content type="html" xml:base="https://mattstockton.com/2026/02/21/what-is-an-agent.html"><![CDATA[<p>This is my attempt to describe what an agent is and why it’s so incredible, yet simple. I’m not going to edit this and I’m not going to run this through an LLM. I’m also going to try to do this in five minutes or less. Let me know how I did, and what I missed that you think is important.</p>

<ul>
  <li>An agent is simply an LLM that can call tools</li>
  <li>A tool is a computer application or a piece of code. For example, opening a file is a tool. Searching for a word in a file is a combination of tools.</li>
  <li>Command line tools have been in existence on computers for a very long time.</li>
  <li>These tools are composable and can solve almost any problem as it relates to files that are on the computer.</li>
  <li>As an example, this ‘tool’:</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cat notes/*.txt | tr '[:upper:]' '[:lower:]' | grep -oE '\b[a-z]{4,}\b' | sort | uniq -c | sort -nr | head
</code></pre></div></div>

<ul>
  <li>Takes all your text notes, normalizes the text, pulls out some words, counts them, and then shows the most common words.</li>
  <li>The tool as read may make no sense to you if you’re not an experienced engineer, but the models know exactly how to ‘do this’ - meaning ‘generate that text and do it’</li>
  <li>With a written instruction like ‘Find the most common topics in my notes.’ - The model has been tuned enough so that it can generate the above tool call.</li>
  <li>Any computer application on your computer is a tool. Excel? It’s a tool. Slack? It’s a tool. Web Browser? Same</li>
  <li>So if you blur your eyes, an agent is something that can simply control your computer. Pretty much any aspect of it.</li>
  <li>So what if a tool doesn’t exist that does what you need the agent to do?</li>
  <li>The agent has a tool that lets it write computer code. This tool is one of the best tools that it has because the foundation labs have spent a lot of time making sure this tool works well.</li>
  <li>And computer code can solve almost any problem.</li>
  <li>So you can have an instruction like: ‘Write me some code that analyzes this image and gives me the exact coordinates of where the red balloon is.’</li>
  <li>Coding agents like Claude Code will see this and then try to write you some code that does that. It will often use other tools in the code itself. So it might download some libraries that it can use or some other techniques that it knows to be able to compose some software to solve the above problem.</li>
  <li>Using a tool like Claude Code, eventually you’ll be able to build some code that solves the problem you’re talking about.</li>
  <li>So what do you have now?</li>
  <li>You have a new tool called the Find the Red Balloon tool.</li>
  <li>And now you can give that tool to the agent so it can just use it next time.</li>
  <li>Basically, you use an agent to build a tool that you can hand to another agent and it can use that tool whenever it needs to.</li>
  <li>So now you can just say, “Find the red balloon in the image.” And the agent will use the tool to do that.</li>
  <li>If the tool works, then it’s going to get it right. You can build deterministic tools that the agent can use. Even though LLMs are at their core, non-deterministic, you can bake in lots of determinism.</li>
  <li>This is the magic, but also the simplicity of agents.</li>
  <li>It’s just an LLM using a computer.</li>
  <li>But it is incredibly flexible, incredibly generalizable, and incredibly composable. So basically you can solve almost any problem.</li>
  <li>The other important thing here is the file system.</li>
  <li>Most systems rely on data to provide any value.</li>
  <li>It turns out if you put data in the right place in a file system, meaning folders on a computer, and you organize that well, the agent can just use tools to find what it needs.</li>
  <li>So basically, agents come down to tools and file systems.</li>
  <li>But those things can be assembled in so many different ways that you can solve incredibly hard problems that truly weren’t solvable before</li>
</ul>

<p>Hope you found this interesting. There are obviously many other details around what agents are. But I really wanted to capture the core essence as I see it in a way that’s accessible to folks. Let me know how I did and how you think about it.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="Software Engineering" /><category term="ai-tools" /><category term="agents" /><category term="llm" /><category term="software-engineering" /><summary type="html"><![CDATA[My attempt to describe what an agent is and why it's so incredible, yet simple.]]></summary></entry><entry><title type="html">We Are Here</title><link href="https://mattstockton.com/2026/02/17/we-are-here.html" rel="alternate" type="text/html" title="We Are Here" /><published>2026-02-17T00:00:00+00:00</published><updated>2026-02-17T00:00:00+00:00</updated><id>https://mattstockton.com/2026/02/17/we-are-here</id><content type="html" xml:base="https://mattstockton.com/2026/02/17/we-are-here.html"><![CDATA[<p>This post is different than my other posts. I’ve found myself trying to write down all of the thoughts I’ve had about what AI is doing, particularly for how we build software. So much has changed and things are moving so fast yet it almost feels like there’s no time to even reflect on it all. And there are so many angles to take and perspectives to have. Meanwhile, things are changing so fast that even those perspectives shift rapidly. So this is my attempt to just get some words down. Not in a narrative forum or with a story or really any coherency, but just a list of thoughts I’ve been having and experiences I’ve been having as it relates to building software.</p>

<p>So why am I writing this down? Partly as a means of reflection. Partly as a way for people who are also thinking about this to feel seen. I don’t think there’s any particular reason or need to feel seen, but just acknowledging that I think there are more and more people who are having these types of thoughts about software, some of which are thrilling and some of which are discomforting. And I’m writing mine down. It’s also for folks who might not have had the time to explore these tools or understand just where we are at. If you read the following and you’re writing software and this all feels just very alien to you, I think it’s worth your time to explore - and I think there is an urgency to explore. My candid advice is that you need to do it now actually.</p>

<p>None of this is meant as a brag or anything of that nature. I’m just stating things as they are happening to me and what I’m seeing. Like the title says: We Are Here.</p>

<p>If you distill it all down to the core essence, It’s that things have changed in software so dramatically over the last six months that it’s truly a completely different thing. If you would have showed me this list three years ago, it would have been completely incomprehensible. I would have told you that there’s no way that these things are true.</p>

<p>So here’s the list and I’m not going to use AI to modify this or to make it sound better. Or anything like that. These are the raw notes.</p>

<ul>
  <li>I have not written a single line of code myself for at least the past four months. Zero.</li>
  <li>I am the most productive I have ever been in my career. And I’m astounded by what I can accomplish on an almost daily basis.</li>
  <li>I’ve never had more fun building.</li>
  <li>My productivity in terms of what I can build has likely 10x’ed compared to two years ago.</li>
  <li>Some things I can build in minutes, where it literally would have taken hours or days before.</li>
  <li>I’ve never felt busier with work, but most of the times that aspect is energizing. I actually have a hard time putting it down, which is a feeling I haven’t had in a number of years. The last time I felt like this was probably when iOS came out and you could build iPhone apps in the late 2000s.</li>
  <li>I rarely use my keyboard anymore, particularly at my home office. It’s just me speaking to my computer using Mac Whisper.</li>
  <li>I find myself reading code less and less. Yes, I am still reading it and I’m not just vibe coding, but I’m finding other ways to ensure the system works as expected without reading all the details. There’s never been a better time to have these tools and still know what good looks like from previous experience.</li>
  <li>I am building software that self-updates. Meaning that it emits information as it runs, and then is able to look at that information after it runs to make improvements to itself.</li>
  <li>I often run “pre-determined commands” (e.g. skills or slash commands) that accomplish ‘operational’ work which would have two years ago, taken me several hours.</li>
  <li>I can multi-task on extremely complex projects in disparate areas without feeling overwhelmed. In fact, sometimes this feels almost necessary with how tools like Claude Code and planning mode work. It’s like the code compiling days all over again.</li>
  <li>I can record myself on a run talking through something I want to do, whether it be a document I want to produce or even a large code change that I want to make. When I get back to my desk, I can use this transcript with a predetermined command. And it almost always is able to one-shot the changes correctly or get very close.</li>
  <li>I spend a lot of my time answering questions that an AI asks me. In fact, one of the most valuable ways to make sure these tools produce what I want them to produce is to allow them to ask me questions exhaustively.</li>
  <li>The tools feel like a superpower now. And they continue to get rapidly better. There are truly step changes that have happened in the last couple months, and there is no sign that this is going to stop.</li>
  <li>I am still surprised by software engineers who don’t see it or who don’t get it who are not doing it. I’m obviously deep in the rabbit hole, but it is so incredibly obvious to me that things have changed forever. Classical software engineering is over.</li>
  <li>There is still an immense need for software engineering talent and specifically systems thinking. There’s never been a better time to apply systems thinking than right now. It feels like a cheat code to have been able to build software classically for the last 20 years and then be able to use these tools now.</li>
  <li>There are still lots of quirks with how to use these tools. Many of the people in this space that I have high regard for are using the tools similarly - but there’s still a a lot of differentiation. The only way to figure this out is to get your hands dirty and do the thing.</li>
  <li>I’m finding myself to be more reliant on AI to do specific things, and less reliant on it to do other things over time. As a specific example, planning mode is absolutely critical now for these tools, and I will spend a ton of time thinking through the plans and trying to build the plans without AI to help me as I first cut. Because that first step that the model takes and the direction it starts heading is enormously important. So it’s worth the time to think critically here.</li>
  <li>So many things in this industry have changed so rapidly, particularly over the last six months. I intellectually believe it’s only going to accelerate but I still don’t fully think I’ve internalized what that means.</li>
  <li>I have no idea where this is all going and definitely have my stretches of anxiety about it all. But I am here for it and I’m going to lean into it and I’m going to try to help others that want to do that too.</li>
</ul>

<p>One more that’s useful to add – and this is the thing that I struggle with the most. I actually feel more and more behind every day. I know I am not, but honestly that is how fast things are moving – and it’s only getting faster.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="Software Engineering" /><category term="ai-tools" /><category term="software-engineering" /><category term="claude-code" /><category term="reflection" /><summary type="html"><![CDATA[Raw, unedited notes on what it feels like to build software right now.]]></summary></entry><entry><title type="html">If You Want to Play Games, You Have to Make Games</title><link href="https://mattstockton.com/2026/02/16/if-you-want-to-play-games-you-have-to-make-games.html" rel="alternate" type="text/html" title="If You Want to Play Games, You Have to Make Games" /><published>2026-02-16T00:00:00+00:00</published><updated>2026-02-16T00:00:00+00:00</updated><id>https://mattstockton.com/2026/02/16/if-you-want-to-play-games-you-have-to-make-games</id><content type="html" xml:base="https://mattstockton.com/2026/02/16/if-you-want-to-play-games-you-have-to-make-games.html"><![CDATA[<p>This post is going to be different than my normal posts in a couple ways. Let me give you the TLDR first in case you want that:</p>

<ul>
  <li>Me and my kids built some games that you can play on the web. They spoke to my computer to build them, and <a href="https://docs.anthropic.com/en/docs/claude-code/overview">Claude Code</a> built them.</li>
  <li>You can go play them now at <a href="https://confettigalaxy.com/">confettigalaxy.com</a>.</li>
  <li>I was stunned at how well this works. I am stunned almost every day by the things I am able to do with AI.</li>
  <li>It made me think more deeply about AI, education, and the skills that matter to be successful in society - something that, upon reflection, I’ve been avoiding thinking about.</li>
</ul>

<figure class=""><img src="/docs/assets/images/confetti-galaxy/landing.png" alt="The Confetti Galaxy landing page" /></figure>

<h2 id="the-story">The Story</h2>

<p>My oldest daughter loves to play this online game platform. It’s web-based and has all these different options to play. Some of the games are fun and educational, but some of them are just mindless. I get it, it’s a fun way to use your time and it’s interactive. But there’s been a bunch of friction about her using it and wanting to use it all the time, and a lot of arguing about when she can use it.</p>

<p>I’ve been meaning to think more deeply about what my true view is on AI as it relates to kids. There’s no question that the entire way kids learn is going to have to fundamentally change. There’s also no question in my mind that the current educational systems will always be behind in figuring out how to integrate these new capabilities into learning experiences. AI is accelerating so fast at this point that the gap is just going to continue to get wider.</p>

<p>As someone who’s incredibly deep in this rabbit hole, I took a step back and tried to ask myself - why haven’t I thought more about this? I think it’s because I don’t have a good solution, and I’m worried about how this change takes shape, particularly for younger people. So it’s avoidance.</p>

<p>AI has made a step change in capabilities in the last three months. Things that have taken me weeks in the past now take me hours or even minutes. And it keeps compounding as you build systems to better utilize these tools.</p>

<p>So taking all of that into account - yesterday I had an idea. I told my daughter that if she wanted to play games, then she had to make games. As an eight-year-old who has no idea what AI is, that concept didn’t mean anything. So I had to show her what I meant. I opened up Claude Code with her. I know how to orchestrate this tool very well at this point because I’m in it every day, so we weren’t starting from scratch and I knew the scaffolding we had to set up. I worked with her and then with my other daughter to build games. I used the system in a way that had it ask us questions about what we’re trying to achieve.</p>

<p>It was super interesting because kids are so creative. They have ideas and oftentimes they have trouble describing them exactly, but as you keep asking them questions, they can really clarify their thinking. We worked through this for a while. I set up a little Q&amp;A workflow using a Claude Code skill, but I also had my kids speak to the computer using Mac Whisper and tell their own ideas about the games. Then we had it build the games. I helped with some of the polish and I knew how to make them a little bit more interactive, but most of these games were the kids’ ideas with me asking them questions about what they wanted them to do.</p>

<p>Within an hour they were playing their own games. Then I told them that their friends can play their games too. I spent a little bit more time with Claude Code working on a plan to deploy these games so that anyone can play them. And here they are on <a href="https://confettigalaxy.com/">confettigalaxy.com</a>.</p>

<p>This was so fun that I built my own game afterwards. I built a game called Go Out For The Pros, which is a game I used to play with my dad at the playground. I described the experience using the skill workflow - what we used to do, how it worked - and it built the game. It’s honestly exactly how I remembered it. Absolutely magical.</p>

<figure class=""><img src="/docs/assets/images/confetti-galaxy/pros.png" alt="Go Out For The Pros - a football catching game set at a playground" /></figure>

<p>My daughter wanted to build a dolphin swimming game where you swim around and collect candy. She described the whole thing herself and we built it together.</p>

<figure class=""><img src="/docs/assets/images/confetti-galaxy/dolphin.png" alt="An underwater dolphin game" /></figure>

<h2 id="the-jumble-of-thoughts">The Jumble of Thoughts</h2>

<p>After this exercise, a lot of thoughts came to the surface that have been lingering for a while. I haven’t fully clarified them all, but it felt useful to just write them down. Here they are in their raw form.</p>

<h3 id="education-is-going-to-change">Education is going to change</h3>

<p>There’s a lot of uncertainty about how AI changes education. Educational systems will always be behind the leading edge, and the gap is only going to get wider. But I think the failure mode is not leaning into it. If you want your kids to understand AI and how it fits into society, I think you have to experiment and do that yourself right now.</p>

<h3 id="the-skills-that-matter-arent-new">The skills that matter aren’t new</h3>

<p>A lot of the skills you need to use AI well aren’t new skills. They’re skills that need to be amplified to take full advantage of this new capability. The ones that come to mind most for me:</p>

<ul>
  <li><strong>Agency.</strong> Do you believe that you can create something yourself, and will you be assertive in taking that initiative? This skill has always been rare and incredibly useful. People who know what agency can do and are assertive about it are in an incredible position to take advantage of these new tools.</li>
  <li><strong>Curiosity.</strong> Are you willing to think about things and make connections across various topics? Are you learning about things well outside of technology that can impact your viewpoints? Curiosity and making connections has never been more valuable.</li>
  <li><strong>Clear thinking and communication.</strong> Can you think through what you’re trying to do and communicate that with clarity? There is a vast difference in outcomes from using these AI tools based on your specificity and your clarity of thought.</li>
  <li><strong>Willingness to iterate.</strong> Do you treat things as things that can improve over time? Do you try to nudge things to improve in an incremental fashion? Utilizing these tools effectively truly requires a feedback loop and iteration, and that’s where you get the compounding. You have to be able to analyze what you’re getting back as the result and figure out how to improve it.</li>
  <li><strong>Comfort with discomfort.</strong> Can you push through the discomfort of trying something new? Even when it feels odd, can you deal with the change and adapt? Things are moving fast and the people who have the mental models to push through that discomfort instead of retreating from it are going to be in a much better position.</li>
</ul>

<p>There are other skills that are useful for AI, but those are the top ones that come to mind. None of them are technical in nature. People have been trying to develop these types of skills for years, even before AI. If you want your kids to be able to thrive in what’s coming with this wave of AI, you need to figure out how to help them learn these skills.</p>

<h3 id="these-skills-are-learnable">These skills are learnable</h3>

<p>Building the games yesterday showed me these skills are learnable with the right environment and the right person helping. My probing questions forced the kids to think more clearly about what they wanted, and they rose to it. And one of the big advantages of learning these skills with these tools is the feedback loop is so tight. You describe something, it builds it, and you can see the progress immediately. The kids were amazed by how fast we could build these games and it gave them a ton of energy to think about what else they could do.</p>

<h3 id="these-tools-are-absolutely-remarkable">These tools are absolutely remarkable</h3>

<p>I intellectually know at this point that these things are extremely capable. My mental model has always been to try to throw your most ambitious project at these tools because they will continue to surprise you. But even with that knowledge, I am continually surprised.</p>

<p>This is a portal my kids can use instead of the previous games they were playing. We can build new games together in about 10 to 15 minutes. They can create their own adventure and then play it. We can build games they want to play instead of the mindless games they’ve been playing. And it forces them to utilize the skills I talked about above.</p>

<p>I think people still truly underestimate how remarkable these tools are. They can do stunning things. As someone who’s deep in this rabbit hole every day, I am stunned on a daily basis. I really think people need to see this for themselves. Dig in, try these things. It’s worth carving off time to do so because it is absolutely astounding what they can do.</p>

<h3 id="equity">Equity</h3>

<p>Education is going to drastically shift given how these tools can be integrated. Some people are starting to figure this out and take action on it. But the folks who have figured it out already have the means, and the technology and the environment to use it are readily available to them. If you look at something like <a href="https://alpha.school/">Alpha School</a>, the results speak for themselves - the improvements in testing outcomes they’re seeing by integrating AI into how kids learn are significant. I think it’s pointing in the right direction. But it’s not accessible to everyone yet, and won’t be for some time.</p>

<p>I’ll be honest - I haven’t spent enough time thinking through how this all plays out at scale. But the opportunity is real. AI enables individually tuned lesson plans in a way that was never before possible, and research on personalized instruction consistently shows it’s more effective than one-size-fits-all approaches. If we don’t figure this out, the disparity in skills and understanding has the possibility to be orders of magnitude greater than anything we’ve ever seen before. How do we democratize access to what I’m talking about in this post in a way that works? How do we ensure as a society that this is available to everyone? I don’t have the answer, but it’s a question we need to be asking.</p>

<h2 id="where-i-landed">Where I Landed</h2>

<p>I know this is a jumble of thoughts and I haven’t truly clarified them all. But they felt important enough to at least begin trying to clarify my thinking on them. The thread running through all of this for me is just acknowledging how much the world is going to change for our youth because of this technology. There are going to be a lot of decisions that need to be made and things that need to change to make sure we’re taking advantage of these remarkable tools, but doing it in a way that’s fair, equitable, and helps people thrive in society and the economy. I don’t have the answers to all of this. Short term, it’s on me to help my kids adapt, and the earlier I can do that the better off they are. But I’ve committed myself to spend more time thinking about this and figuring out what my role in it is beyond my own family.</p>

<p>On a lighter note, definitely check out the games at <a href="https://confettigalaxy.com/">confettigalaxy.com</a> because they are pretty fun. And if you’re curious about how you can build these games with your kids, I’ll do a follow-up post that is more technical in nature to show exactly what I did.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="Personal Reflections" /><category term="AI" /><category term="Claude Code" /><category term="Education" /><category term="Parenting" /><summary type="html"><![CDATA[I had my kids build their own games using Claude Code, and it got me thinking about AI, education, and equity.]]></summary></entry><entry><title type="html">I Published My Portfolio Analysis Workflow - Try It Yourself</title><link href="https://mattstockton.com/2026/02/12/portfolio-analysis-skill-for-claude-code.html" rel="alternate" type="text/html" title="I Published My Portfolio Analysis Workflow - Try It Yourself" /><published>2026-02-12T00:00:00+00:00</published><updated>2026-02-12T00:00:00+00:00</updated><id>https://mattstockton.com/2026/02/12/portfolio-analysis-skill-for-claude-code</id><content type="html" xml:base="https://mattstockton.com/2026/02/12/portfolio-analysis-skill-for-claude-code.html"><![CDATA[<p>I recently wrote about <a href="/2026/02/10/building-a-portfolio-optimization-plan-with-claude-code.html">using Claude Code to build a portfolio optimization plan</a> - I fed it our brokerage CSV exports, described our goals, and iterated over several sessions until it produced a phased action plan with tax impact analysis and fund recommendations. That post ended with a section called “If You Want to Try This” with tips on how to do it yourself from scratch. After it went up, a few people asked if I could just share the workflow so they didn’t have to start from zero.</p>

<p>So I did: <a href="https://github.com/MattStockton/portfolio-analysis">MattStockton/portfolio-analysis</a>.</p>

<p>If you haven’t used <a href="https://docs.anthropic.com/en/docs/claude-code/overview">Claude Code</a> skills before - a skill is basically a set of instructions you give Claude so it knows how to do something specific. It’s not code or a traditional app. It’s markdown files that describe a workflow, and Claude follows them when you ask it to do that thing. Because it’s just text, it’s not locked to Claude Code either. You could drop these files into a Claude project on claude.ai, use them with another AI tool, or just read them and adapt the approach yourself.</p>

<h2 id="what-i-changed-to-make-it-reusable">What I Changed to Make It Reusable</h2>

<p>My original project was built around my specific situation. The parsers only handled the brokerage formats I happened to use. The fund classifications were built up one session at a time as Claude encountered my specific holdings. My tax calculations were hardcoded to my bracket. My allocation targets were baked into the project context. All of that worked great for me but wasn’t useful to anyone else.</p>

<p>To generalize it, I had Claude help me work through each of those pieces. The parsing logic now reads whatever headers are in your file and writes a parser on the fly instead of expecting my specific column layouts. I pulled the fund classifications into a reference database of 190+ funds across eight brokerages, with keyword matching for anything not in the database. Tax calculations got their own reference file covering federal and state brackets. And the allocation targets are now a set of seven templates (or custom) you can pick from or ignore entirely and define your own.</p>

<p>The other big thing was the workflow itself. In my original project, I wrote a long goal prompt and then iterated with Claude over several sessions. That worked because I was willing to put in the time and I knew what I was looking for. For someone picking this up cold, that’s a lot to figure out. So the skill breaks it into six steps with structured questions at each one - you’re picking from options instead of writing freeform prompts.</p>

<p>The goal was to get people 80% of what I got without having to do all the upfront work I did. The other 20% comes from the back-and-forth - clarifying your specific constraints, pushing back on recommendations, iterating until the plan fits your situation.</p>

<h2 id="what-you-get-out-of-it">What You Get Out of It</h2>

<p>You provide CSV exports from your brokerage accounts and the skill handles parsing them - Fidelity, Schwab, Vanguard, E*TRADE, Merrill, or whatever else. It reads the headers and figures out the format.</p>

<p>From there it classifies your holdings, runs a gap analysis against your targets, checks for tax-inefficient placements (like bonds in taxable accounts or cash sitting in Roth space), and looks at whether your recurring contributions are closing gaps or making them worse.</p>

<p>Then it puts together a phased action plan. Free moves in retirement accounts first, then low-tax fixes, then contribution changes, then long-term hold-and-dilute strategies. Each recommendation includes the specific fund, amount, account, tax cost, and rationale.</p>

<h2 id="try-it">Try It</h2>

<p>You need CSV exports from your brokerage accounts - most brokerages have a “Download” or “Export” button on the positions page. When you export, look for options to include extra fields like cost basis, Morningstar category, expense ratio, and fund ratings. The skill can figure a lot of this out from the fund symbol alone, but having it in the export gives it better data to work with. The <a href="https://github.com/MattStockton/portfolio-analysis">repo README</a> has setup instructions. I built it as a Claude Code skill, but you don’t need Claude Code specifically. The skill files are just markdown - if you upload them to claude.ai, ChatGPT, or any other AI tool that lets you provide reference files, it should pick up the workflow and do its best with it.</p>

<p><strong>Privacy:</strong> The skill is just markdown files - it doesn’t collect or send anything anywhere. Your brokerage data goes to your LLM provider as part of the conversation, same as anything else you share in these tools.</p>

<p><strong>Limitations:</strong> US tax system only. Tax brackets are based on 2025 law. Default templates lean toward index funds but it supports active and blended approaches. Not financial advice.</p>

<h2 id="last-thing">Last Thing</h2>

<p>Your situation is different from mine and you’ll probably want to modify things. The skill is just markdown files - you can change the instructions, add your own constraints, or take it somewhere I didn’t. How far you get depends on how much effort you put into the back-and-forth.</p>

<p>Beyond the portfolio stuff, I think the more interesting idea is that this pattern works for any domain. If you’ve built up a good workflow with an AI tool over multiple sessions, you can probably extract it into a skill that other people can pick up and run with.</p>

<p>If you try it, let me know how it goes. Open an issue on the <a href="https://github.com/MattStockton/portfolio-analysis">repo</a> if something doesn’t work or if your brokerage format trips it up.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="Finance &amp; Investing" /><category term="personal-finance" /><category term="ai-tools" /><category term="claude-code" /><category term="portfolio-analysis" /><category term="workflow" /><summary type="html"><![CDATA[People asked me to share the portfolio optimization workflow from my last post. I turned it into a Claude Code skill you can install and try with your own brokerage data.]]></summary></entry><entry><title type="html">How I Built a Portfolio Optimization Plan with Claude Code</title><link href="https://mattstockton.com/2026/02/10/building-a-portfolio-optimization-plan-with-claude-code.html" rel="alternate" type="text/html" title="How I Built a Portfolio Optimization Plan with Claude Code" /><published>2026-02-10T00:00:00+00:00</published><updated>2026-02-10T00:00:00+00:00</updated><id>https://mattstockton.com/2026/02/10/building-a-portfolio-optimization-plan-with-claude-code</id><content type="html" xml:base="https://mattstockton.com/2026/02/10/building-a-portfolio-optimization-plan-with-claude-code.html"><![CDATA[<p>I saw the below tweet recently and I did exactly this. Over multiple sessions with Claude Code, I fed it our brokerage CSVs, described our goals and constraints, and worked with it to produce a portfolio optimization plan - phased actions, tax impact analysis, fund recommendations, before-and-after allocation grids. The kind of plan you’d pay a financial advisor to put together, except I built it with an AI.</p>

<p><a href="https://x.com/buccocapital/status/2021290232205676944"><img src="/docs/assets/images/ai-financial-advisor/buccocapital-tweet.png" width="500px" /></a></p>

<p>A year ago, I wrote about <a href="/2025/02/07/buildling-a-personal-finance-tool-with-ai.html">building a personal finance tool in a day with AI</a>. That project required software development - I used AI to help me build an application with a UI, data pipelines, and visualization components. Models have gotten flexible enough that you don’t need to build an app anymore. An agent like Claude Code can read your files, write scripts, run them, and iterate on the output directly.</p>

<figure>
<img src="/docs/assets/images/ai-financial-advisor/workflow-infographic.png" />
<figcaption><em>Overview of the workflow - from raw data and goal prompt through iteration to the final plan</em></figcaption>
</figure>

<h2 id="setting-up-the-workspace">Setting Up the Workspace</h2>

<p>I used <a href="https://docs.anthropic.com/en/docs/claude-code/overview">Claude Code</a>, which runs in a terminal and can read and write files on your machine. I pointed it at a directory with all my financial data. Portfolio analysis is a good fit for this because there’s a lot of messy data in different formats that the model can just dig through directly.</p>

<p>I started with <strong>three inputs</strong>:</p>
<ul>
  <li><strong>CSV exports</strong> from my various financial accounts - holdings, amounts, cost basis, fund fees, fund ratings, and a ton of other data the model could use</li>
  <li><strong>A supplementary text file</strong> - there was other information I knew the model would need but no good way to export it, so I typed up a scratchpad with a bulleted list of things like bank balances, 529s, employer retirement account details, and automated investment settings. Not structured, but it had the raw numbers.</li>
  <li><strong>A goal prompt</strong> describing what I wanted</li>
</ul>

<p>The goal prompt was the most important piece. I spent a lot of time on it and wrote it mostly by hand before having the AI review it - I wanted to force myself to think through all of our constraints and goals. I included:</p>

<ul>
  <li><strong>What data exists and where</strong> - a narrative of what files are in the directory and what the model should be considering</li>
  <li><strong>The desired output format</strong> - I brainstormed the kinds of things I wanted to see: allocation tables, style-box grids, holdings charts, different ways to slice the data. And ultimately, a concrete plan for how to modify the portfolio to get to a target allocation.</li>
  <li><strong>Our preferences</strong> - I want the portfolio to be tax efficient, I’d rather find the lowest fee ETFs that are good than chase performance, and I don’t want to overcomplicate things. I’m well-versed in this stuff but complexity isn’t the goal.</li>
  <li><strong>Known constraints</strong> - everyone has their own nuances. For us, we’d decided not to touch the allocations or ongoing contributions for a specific account, so I called that out as a constraint.</li>
  <li><strong>What we suspected was wrong</strong> - I had a view on things that could be better, so I included it, but I caveated it with “if you have a different view, I want to hear it.” I didn’t want to oversteer the model toward a specific outcome. If you have insight that can nudge it in the right direction, it’s worth providing - just make sure you give it room to look outside your ideas too.</li>
  <li><strong>Strawman proposals</strong> - I included our own rough ideas for target allocations and investment changes. Even if they’re wrong, it gives the model a starting point to react to rather than building from scratch.</li>
  <li><strong>“Ask me questions exhaustively”</strong> - I put this at the end of the prompt. It gets the AI to ask clarifying questions before jumping straight to conclusions, which makes the first plan way better.</li>
</ul>

<p>I also built up a <code class="language-plaintext highlighter-rouge">CLAUDE.md</code> file - project instructions that Claude reads at the start of every session. I had Claude set it up initially after asking me some questions, but after a couple sessions I started having Claude update it with any learnings from each session. Over time it became the project’s memory - data quirks, strategy decisions, target allocations. When I came back days later, Claude picked up right where we left off.</p>

<h2 id="parsing-the-mess">Parsing the Mess</h2>

<p>Once I had the goal prompt and data ready, I handed the wheels over. Claude (Opus 4.6) worked for a while on its own - writing Python scripts to parse all the CSVs, classify every holding into target categories, handle encoding issues, deduplicate overlapping exports, and deal with non-standard line items that would get misclassified. It iterated through problems as it hit them and ended up in a really good place. The baseline it produced - a full gap analysis across every account and category - was impressive enough to start working from immediately.</p>

<h2 id="iterating-as-thought-partners">Iterating as Thought Partners</h2>

<p>The initial plan identified overweight categories, found tax-location violations, recommended specific fund swaps with expense ratio comparisons and Morningstar ratings, and calculated one-time tax costs versus ongoing savings. It even recommended tax-loss harvesting partner funds for every new position.</p>

<p>From there, it was like working with an analyst who has all the data but hasn’t lived with the accounts. I’d clarify something or reframe a constraint, and Claude would update every calculation, table, and recommendation in the plan. A few examples:</p>

<p><strong>I refined our international allocation with Claude.</strong> The initial plan had a single “international” bucket, but I wanted more nuance - specific targets across value vs. growth, small vs. large. I worked back and forth with Claude to figure out what that breakdown should look like and which funds would get us there. That kind of allocation decision is hard to think through alone because every change affects the rest of the portfolio.</p>

<p><strong>I asked Claude to self-critique</strong> - “rate this plan 1-10 and tell me what you’d change.” It gave itself a 7.5 and identified seven improvements. The biggest was hiding in plain sight: we had a large overweight position sitting in tax-free retirement accounts, where selling costs literally zero in taxes. The original plan had left it untouched. It also caught that its own retirement account deployment was putting money into a category that was already overweight. I approved the changes but asked for a phased approach rather than all-at-once.</p>

<p><strong>I reframed which accounts count toward targets.</strong> We decided to treat my wife’s employer retirement account as static for now - we wouldn’t touch it or change its allocations. This is an artificial constraint, but it simplifies the plan, and once we lock in the other changes we can always run the process again with new constraints if we want to modify that account later. The initial analysis left it out entirely. But it still holds real money in specific categories, and that affects what the rest of the portfolio needs to do.</p>

<p>Once I pointed this out, Claude built a combined framework quickly: define targets for the full portfolio, subtract what the static account provides, and optimize the rest to fill the gaps. Some overweight categories got worse, some underweight ones became more urgent, and the recommended purchases changed.</p>

<h2 id="what-it-produced">What It Produced</h2>

<p>I ended up with a ten-section plan document with appendices - and several sections went beyond what I asked for:</p>

<ul>
  <li><strong>Complete portfolio snapshot</strong> - Every account, every holding, with cost basis, embedded gains, expense ratios, and tax treatment. All parsed automatically from the raw CSV exports.</li>
  <li><strong>Gap analysis across ten fund categories</strong> - Current allocation versus targets, with the dollar gap and priority level for each. Included a visual bar chart showing the drift and a nine-box style grid (value/blend/growth vs large/mid/small) showing the portfolio tilt before and after.</li>
  <li><strong>Combined portfolio framework</strong> - A table showing how an account we’d decided not to touch still changes the effective targets for the rest of the portfolio.</li>
  <li><strong>Four-phase sequenced action plan</strong> - Concrete steps organized from “execute this week” through “ongoing quarterly.” Each action specified the fund, the dollar amount, the account, the tax cost, and the rationale. Separate actions for retirement accounts (zero tax) versus taxable (calculated tax impact).</li>
  <li><strong>Tax impact summary with payback periods</strong> - A table for every recommended trade showing the gain, tax cost, annual tax savings, and the breakeven timeline. A separate table for positions explicitly <em>not</em> recommended to sell - calculating the tax cost if you did sell and explaining why the math didn’t work.</li>
  <li><strong>Fund recommendations with deep research</strong> - An active buy list, a stop-buying list, and a hold-and-dilute list. Claude compared candidates on factor loadings, expense ratios, Morningstar ratings, AUM, and whether they screen out low-quality companies. Each recommendation included a tax-loss harvesting partner: a similar-but-not-identical fund from a different provider, so if a position drops you can capture the loss and immediately buy the partner to maintain exposure without triggering wash sale rules.</li>
  <li><strong>Tax location matrix</strong> - Which asset type belongs in which account type (pre-tax, Roth, taxable) and why, with a list of current violations and the action to fix each one.</li>
  <li><strong>Retirement contribution structure optimization</strong> - Claude looked at my wife’s employer retirement contributions unprompted and found that switching one component from after-tax to pre-tax treatment would save thousands annually, with the ability to convert at much lower rates during early retirement.</li>
  <li><strong>Natural dilution timeline</strong> - Projections for how long each overweight category takes to reach target through new money allocation alone, accounting for recurring contributions and dividend flows.</li>
</ul>

<figure>
<img src="/docs/assets/images/ai-financial-advisor/allocation-shift.png" width="450px" />
<figcaption><em>Anonymized excerpt from the plan - before/after allocation shift across categories</em></figcaption>
</figure>

<figure>
<img src="/docs/assets/images/ai-financial-advisor/style-grid.png" width="400px" />
<figcaption><em>Anonymized excerpt from the plan - nine-box style grid showing portfolio tilt</em></figcaption>
</figure>

<figure>
<img src="/docs/assets/images/ai-financial-advisor/tax-impact-analysis.png" width="400px" />
<figcaption><em>Anonymized excerpt from the plan - tax impact and payback period for a recommended trade</em></figcaption>
</figure>

<p>To be clear, this wasn’t a science experiment. I’m actively using this plan and I’m almost done executing it. I had Claude remix the full document into a shorter checklist so I can scan it and check things off as I go.</p>

<h2 id="if-you-want-to-try-this">If You Want to Try This</h2>

<ul>
  <li><strong>Export everything you can into files.</strong> Download CSV holdings from every brokerage account. Create a text file for anything without an export - bank account balances, employer retirement plan details (holdings, contribution amounts, fund options), automated investment settings, any pending changes you’re considering.</li>
  <li><strong>Write a detailed goal prompt.</strong> State your tax situation, risk tolerance, and time horizon. List your constraints - accounts you don’t want to touch, positions you can’t sell, contribution limits. Include what you already suspect is wrong. Add a strawman target allocation if you have one - it gives the AI something concrete to react to. Ask for a sequenced action plan, not general advice. And end with <strong>“ask me questions exhaustively”</strong> - the AI will ask clarifying questions instead of filling in the blanks, so you’re not leaving anything ambiguous about what you actually want.</li>
  <li><strong>Iterate like you would with a human advisor.</strong> The first plan will be solid but will miss things only you know about your accounts. Each clarification is fast; the AI updates every calculation in the plan instantly. Ask it to rate its own plan 1-10 - it’ll find things it missed.</li>
  <li><strong>Build project context that persists.</strong> If you’re using Claude Code, a <code class="language-plaintext highlighter-rouge">CLAUDE.md</code> file in your project directory carries across sessions. Add key decisions, data quirks, and what you’ve figured out as you go. Every future session builds on everything that came before.</li>
</ul>

<h2 id="the-work-compounds">The Work Compounds</h2>

<p>This blog post was written with the help of Claude Code. I pointed it at the same project directory, told it to read the session history and plan documents, and asked it to write a post about the process. The work you do with these tools compounds - you can distill it into other artifacts or remix it with other content. The prompt that kicked off this session:</p>

<p><img src="/docs/assets/images/ai-financial-advisor/blog-post-prompt.png" width="900px" />
<br /></p>

<p>Because the project context was already in the filesystem - the optimization plan, the session summaries, the strategy decisions - Claude had everything it needed to draft the post. I iterated on it from there, but the starting point was strong because all the context was already there from previous sessions.</p>

<p>A year ago this would have been a week of spreadsheet work or a few thousand dollars to a financial advisor. Instead it was a few evenings of back-and-forth with an AI, and the plan it produced is the one we’re executing.</p>]]></content><author><name>Matt Stockton</name><email>mattstockton@gmail.com</email></author><category term="Finance &amp; Investing" /><category term="personal-finance" /><category term="ai-tools" /><category term="claude-code" /><category term="portfolio-analysis" /><category term="workflow" /><summary type="html"><![CDATA[I fed our brokerage data into Claude Code and iterated over multiple sessions to produce a portfolio optimization plan - phased actions, tax impact analysis, fund recommendations. From messy CSVs to an actionable plan we're now executing.]]></summary></entry></feed>