<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-7022755517551007355</atom:id><lastBuildDate>Mon, 24 Aug 2026 19:36:58 +0000</lastBuildDate><category>Delphi</category><category>News</category><category>TCanvas</category><category>Open Source</category><category>Java</category><category>Maths</category><category>Delphi 2010</category><category>Pragmatic Programming</category><category>Tools</category><category>VLO Framework</category><category>Components</category><category>Computational geometry</category><category>Python</category><category>English</category><category>Extreme Programming</category><category>Delphi XE</category><category>AGILE</category><category>Videos</category><category>Internet</category><category>Design patterns</category><category>Utilities</category><category>Artificial Intelligence</category><category>IDE Delphi</category><category>Physics</category><category>Eclipse</category><category>Operating System</category><category>.NET</category><category>Vijeo Citect</category><category>Productivity</category><category>Windows</category><category>openAI</category><category>Encryption Algorithms</category><category>P-Zaggy</category><category>Robotics</category><category>API Windows</category><category>Force-Directed Graph</category><category>Image processing</category><category>Indy</category><category>TED</category><category>Configuration library</category><category>Data Bases</category><category>Machine Learning</category><category>Subversion</category><category>llm</category><category>2D</category><category>Aspect oriented programming</category><category>COM Objects</category><category>Industrial Automation</category><category>MySQL</category><category>RTTI</category><category>Raspberry Pi</category><category>Regular Expressions</category><category>Scada</category><category>Security</category><category>Debug</category><category>Education</category><category>Excel</category><category>JBoss</category><category>SQL Server</category><category>Software configuration</category><category>communications</category><category>github</category><category>google guice</category><category>neuroplasticity</category><category>.net core 3.0</category><category>3D</category><category>AI Agents</category><category>ASP.NET</category><category>Android</category><category>Chaining Method</category><category>Continuous Integration</category><category>Cryptography</category><category>Dependency Injection</category><category>Google</category><category>Google Chrome</category><category>HTML</category><category>JDBC</category><category>JSON</category><category>JavaScript</category><category>LangChain</category><category>Lazarus</category><category>Linux</category><category>Microsoft</category><category>Molecules</category><category>Ollama</category><category>OpenSSL</category><category>Parse.com</category><category>Persistence</category><category>RAG</category><category>REST</category><category>Services</category><category>Ubuntu</category><category>nodejs</category><category>ruby</category><category>wetware</category><category>AI</category><category>API</category><category>Advanced Encryption Standard</category><category>Atom table</category><category>Code Coverage</category><category>Delphi10.2Tokyo</category><category>DevExpress</category><category>Extensions</category><category>Free Pascal</category><category>IT</category><category>Icons</category><category>Industrial Control</category><category>Kernel</category><category>Local LLM</category><category>MVC</category><category>Messaging</category><category>Routes</category><category>Scripts</category><category>Scrum</category><category>TDD</category><category>TeamCity</category><category>Virtual machines</category><category>Windows Mobile</category><category>XML</category><category>csv</category><category>games</category><category>portfolio-optimization</category><category>riskoptima</category><category>ADO</category><category>BaaS</category><category>Blogger</category><category>ChatBot</category><category>Cloud</category><category>Code Quality</category><category>Code Reviews</category><category>ComfyUI</category><category>Compilers</category><category>Compliance Automation</category><category>Console</category><category>Convex Hull</category><category>DLL</category><category>DUnit</category><category>Delphi XE6</category><category>DelphiBerlin</category><category>Devops</category><category>Dijkstra</category><category>Docker</category><category>Exceptions</category><category>FIT</category><category>Facebook</category><category>Finance</category><category>Financial Regulation</category><category>Firebase</category><category>Generics</category><category>Graph Visualization</category><category>Hacking</category><category>Hibernate</category><category>Investment</category><category>Kubernetes</category><category>LINQ</category><category>LangGraph</category><category>LoRA</category><category>MiFID II</category><category>Mock</category><category>NDepend</category><category>Notification</category><category>OLE</category><category>Object oriented programming</category><category>Pair Programming</category><category>Parsing</category><category>Photography</category><category>Prim Algorithm</category><category>Private AI</category><category>Profiling</category><category>RPi3</category><category>RSA</category><category>Redes</category><category>Refactoring</category><category>Ribbon Controls</category><category>SQL</category><category>SSL</category><category>Science</category><category>Sharing</category><category>Skills</category><category>TStringGrid</category><category>UOC</category><category>Unicode</category><category>Unit Testing</category><category>University</category><category>VSCode</category><category>WMI</category><category>Web API</category><category>WorkFlow</category><category>XML-RPC</category><category>ZeosDBO</category><category>actions</category><category>bot</category><category>codex</category><category>deployment</category><category>efficient-frontier</category><category>flickr</category><category>gnuplot</category><category>library</category><category>monte-carlo</category><category>neuroscience</category><category>portfolio</category><category>redmine</category><category>telegram</category><category>.net 5</category><category>.net 9</category><category>.net core 2.1</category><category>.net core 3.1</category><category>AG2</category><category>AI Chatbot</category><category>AI Coding Agents</category><category>AI workflow</category><category>AIAgents</category><category>AICodingAssistant</category><category>AJAX</category><category>ASCII</category><category>ASP.NET Core</category><category>AST Evaluation</category><category>Abstract Factory</category><category>Access</category><category>ActiveX</category><category>Agent Orchestration</category><category>Agentic AI</category><category>AgenticAI</category><category>Alpha-beta pruning</category><category>Analytics</category><category>AspectJ</category><category>Augmented Reality</category><category>AutoGen</category><category>BackEnd</category><category>Backup</category><category>Base64</category><category>C#</category><category>C++</category><category>CLI</category><category>CNN</category><category>CUP</category><category>Calculator Tool</category><category>CatvsDog</category><category>Certification</category><category>Chainlit</category><category>Claude Code</category><category>Clipboard</category><category>Cloud Computing</category><category>Cloudflare</category><category>CodeLlama7B</category><category>Comparison</category><category>Compression</category><category>Concordion</category><category>ContinueExtension</category><category>CrewAI</category><category>CruiseControl</category><category>Currency</category><category>DBase</category><category>DLTK</category><category>Data Analysis</category><category>Data Recovery</category><category>Data Science</category><category>Data Visualization</category><category>Death March</category><category>Debian</category><category>Deep Learning</category><category>Delegates</category><category>Delphi XE5</category><category>Delphi XE7</category><category>Delphi10Seattle</category><category>DelphiFMX</category><category>DelphiTokyo</category><category>Deterministic AI</category><category>Developer Tooling</category><category>DeveloperProductivity</category><category>Devices</category><category>Diaspora</category><category>Digital Identity</category><category>Direct2D</category><category>EADS</category><category>ERP</category><category>ESMA</category><category>Entrepreneur</category><category>Exif</category><category>Files</category><category>Flash</category><category>FontAwesome</category><category>Forecasting</category><category>Fractals</category><category>Fuzzy</category><category>GEO</category><category>GPT-4o</category><category>GPT‑2</category><category>Game</category><category>Geek</category><category>Generative AI</category><category>GenerativeAI</category><category>Genetic Algorithms</category><category>Google Maps</category><category>Google Noop</category><category>Google SketchUp</category><category>Google insight</category><category>Google wave</category><category>Gource</category><category>GraphBasedWorkflows</category><category>HTTPS</category><category>Hardware</category><category>HuggingFace</category><category>IDE</category><category>IPTC</category><category>ISA</category><category>InceptionResnetV2</category><category>InnoSetup</category><category>Interface oriented programming</category><category>J2EE</category><category>JEDI</category><category>JUnit</category><category>Jenkins</category><category>Jflex</category><category>Jobs</category><category>Kanban</category><category>Keras</category><category>KeyStrokes</category><category>Kinvey</category><category>LLM inference</category><category>LLM integration</category><category>LLM tool calling</category><category>LSTM</category><category>LocalLLM</category><category>MCP Client</category><category>MCP Server</category><category>MVC5</category><category>Matlab</category><category>Matplotlib</category><category>MiFID II/III Updates</category><category>MiFIR</category><category>Modbus</category><category>Multi-Agent AI (CrewAI)</category><category>NAS</category><category>NUnit</category><category>Near Real-Time Reporting</category><category>NetStat</category><category>OSGi</category><category>Observability</category><category>Offline AI</category><category>OfflineCopilot</category><category>OpenAI GPT-4o</category><category>PCB</category><category>PDF</category><category>PDFSearchTool</category><category>PFOF Ban &amp; Consolidated Tape</category><category>PHP</category><category>PPL</category><category>PaaS</category><category>Pandas Agent</category><category>Pathfinding</category><category>Peaberry</category><category>Penjili</category><category>Perl</category><category>Powershell</category><category>Prezi</category><category>PrivacyFirstAI</category><category>Processing</category><category>Prompt</category><category>Prompt Engineering</category><category>PushNotifications</category><category>Pydantic</category><category>Python CLI</category><category>QR2</category><category>Qwen</category><category>R2build</category><category>RPC</category><category>RSS</category><category>ReAct</category><category>RegTech</category><category>Registro Windows</category><category>ReportBuilder</category><category>Restful</category><category>Retrieval Augmented Generation</category><category>SDK</category><category>SDXL</category><category>SMTP</category><category>SOAP</category><category>SP500</category><category>Safe Evaluation</category><category>Sequence Diagrams</category><category>Servlet</category><category>SignalR</category><category>Simuladores</category><category>Speech SDK</category><category>StableDiffusion</category><category>Steve Jobs</category><category>Storage</category><category>Streaming</category><category>Streaming Outputs</category><category>Subclipse</category><category>Syntax Highlighting</category><category>TBookMark</category><category>TCustomAttributes</category><category>TFN</category><category>TKinter</category><category>Task</category><category>Task-Centric AI</category><category>TensorFlow</category><category>Thiessen</category><category>Tool Calling</category><category>ToolsAndOrchestration</category><category>Trac</category><category>Tron</category><category>UML</category><category>UTF-8</category><category>VBA</category><category>VCL</category><category>VIX</category><category>VNC</category><category>VS Code</category><category>Vanguard</category><category>Visprint</category><category>Visual Studio 2019</category><category>Voronoi</category><category>Vulkan</category><category>WSDL</category><category>Web Service</category><category>WinRM</category><category>Windows10</category><category>Windows11Dev</category><category>Winsock</category><category>YouTube summarization</category><category>Zaluum</category><category>ai‑workflow</category><category>algebra</category><category>algorithmic</category><category>analysis</category><category>analysis suite</category><category>arcade</category><category>architecture</category><category>art</category><category>asset allocation</category><category>automation</category><category>backtesting</category><category>budgeting</category><category>bugs</category><category>charts</category><category>chunked summarization</category><category>classification</category><category>cloning studio</category><category>code rush</category><category>command</category><category>competition</category><category>compliance</category><category>computing</category><category>continuous batching</category><category>copilot</category><category>copyright</category><category>correlation</category><category>csharp</category><category>dev‑environment</category><category>diagram</category><category>diff</category><category>divergenge</category><category>dotCover</category><category>dynamic portfolio</category><category>dynamic quantization</category><category>eReader</category><category>ebook</category><category>email signature</category><category>exporter</category><category>external</category><category>fictional personas</category><category>film</category><category>fireworks</category><category>fixed chain</category><category>fun</category><category>function calling</category><category>fundamental rights</category><category>funds</category><category>gemma 4</category><category>git</category><category>gpt</category><category>greeks</category><category>group chat</category><category>heroku</category><category>index</category><category>inheritance</category><category>instruments</category><category>investment advisor</category><category>investment strategies</category><category>jqplot</category><category>kaggle</category><category>large files</category><category>latency reduction</category><category>layer</category><category>llama.cpp</category><category>local voice</category><category>local web app</category><category>logger</category><category>lua</category><category>macroeconomics</category><category>map-reduce</category><category>market analysis</category><category>matrix</category><category>mean-variance</category><category>memory reduction</category><category>mobile</category><category>mobile device</category><category>mouse</category><category>multi-agent</category><category>network</category><category>ocr</category><category>openclaw</category><category>options</category><category>orchestrator-worker pattern</category><category>overlap</category><category>owasp</category><category>parallel</category><category>password</category><category>performance</category><category>performance optimization</category><category>private repository</category><category>protobuf</category><category>pygame</category><category>quant</category><category>quant developer</category><category>quantization</category><category>qwen3</category><category>recommendation</category><category>recursive agent</category><category>reference library</category><category>reflection pattern</category><category>regulatory</category><category>remoting</category><category>repositories</category><category>responsive</category><category>risk grades</category><category>risk tolerance</category><category>scripting</category><category>self-hosting</category><category>serilog</category><category>simulation</category><category>simulator</category><category>social networks</category><category>spectre.console</category><category>straddle</category><category>suite</category><category>supercomputer</category><category>tesseract</category><category>testing</category><category>threading</category><category>throughput improvement</category><category>trading</category><category>training</category><category>tunnel</category><category>tutor</category><category>tutorial</category><category>twitter</category><category>vibe coding</category><category>visualization</category><category>vol</category><category>web-scraping</category><category>weight‑only quantization</category><category>whatsapp</category><category>windows service</category><category>wsl2</category><category>youtube-transcript-api</category><category>yt-dlp</category><title>Random thoughts on coding and technology</title><description>I’m a Senior Full-Stack &amp;amp; Quantitative Engineer working across trading, compliance, risk, and AI systems. This blog is where I write about practical engineering: Python, .NET, quantitative tooling, local/hybrid LLM workflows, and the systems thinking behind real-world software.</description><link>https://thundaxsoftware.blogspot.com/</link><managingEditor>noreply@blogger.com (Unknown)</managingEditor><generator>Blogger</generator><openSearch:totalResults>558</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-873941484809646276</guid><pubDate>Mon, 24 Aug 2026 19:36:58 +0000</pubDate><atom:updated>2026-08-24T19:36:58.935+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">llama.cpp</category><category domain="http://www.blogger.com/atom/ns#">Local LLM</category><category domain="http://www.blogger.com/atom/ns#">Private AI</category><category domain="http://www.blogger.com/atom/ns#">Qwen</category><category domain="http://www.blogger.com/atom/ns#">Vulkan</category><title>Building a Private Local LLM Server on Windows with llama.cpp, Vulkan and Qwen</title><description>&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCFcQwi3mpysRQ5-UxPFha61OHb95WFausBnsIxdwNPFxDEIO1noo-HkoybQybppY97AFbKzj6BQkpfLwe6On4no0gnTIcXxH0AFGUhc54GXfd6fG7NPYHLHq0YPXbniXflHqkKIasq0sUqtvW-cDnMezT60E2sIo6dJp04NrM4kqJewtKpzWJjRtokrQ/s1672/ChatGPT%20Image%20Aug%2024,%202026,%2008_12_37%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;941&quot; data-original-width=&quot;1672&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCFcQwi3mpysRQ5-UxPFha61OHb95WFausBnsIxdwNPFxDEIO1noo-HkoybQybppY97AFbKzj6BQkpfLwe6On4no0gnTIcXxH0AFGUhc54GXfd6fG7NPYHLHq0YPXbniXflHqkKIasq0sUqtvW-cDnMezT60E2sIo6dJp04NrM4kqJewtKpzWJjRtokrQ/s320/ChatGPT%20Image%20Aug%2024,%202026,%2008_12_37%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;I wanted to turn an existing &lt;b&gt;Windows machine&lt;/b&gt; into a fully self-hosted LLM server: no cloud inference, no OpenAI dependency, and an API that my own applications could call in essentially the same way they call OpenAI or Ollama.&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The hardware was not designed as an AI workstation:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;CPU:&lt;/strong&gt; AMD Ryzen 5 7430U&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cores:&lt;/strong&gt; 6 cores / 12 threads&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;RAM:&lt;/strong&gt; 32 GB&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;GPU:&lt;/strong&gt; AMD Radeon integrated graphics&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;GPU backend:&lt;/strong&gt; Vulkan&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;OS:&lt;/strong&gt; Windows&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dedicated VRAM:&lt;/strong&gt; only around 512 MB&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shared GPU memory:&lt;/strong&gt; approximately 16 GB&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgIj8fTA4h2S4cqr4O71SFQ6BJtKvsAf9s907TsHTw9Hg1UE1DKnYVsAmOnH--C4r7uJvtJnlQAK6MDySxbMH23fBe0eu6gmoBOt5O3fnrzsaEw6hU-3gq7Phh2nwCocaAa_6agFMHjwiAr8F3Q4DvBGq-_pgyJ8HfX2UxgKe_U9NYCFjdTF1vEOnXCBSE&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1500&quot; data-original-width=&quot;1200&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgIj8fTA4h2S4cqr4O71SFQ6BJtKvsAf9s907TsHTw9Hg1UE1DKnYVsAmOnH--C4r7uJvtJnlQAK6MDySxbMH23fBe0eu6gmoBOt5O3fnrzsaEw6hU-3gq7Phh2nwCocaAa_6agFMHjwiAr8F3Q4DvBGq-_pgyJ8HfX2UxgKe_U9NYCFjdTF1vEOnXCBSE=w320-h400&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Despite those limitations, the final result was:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Windows Server
     │
     ▼
llama.cpp + Vulkan
     │
     ▼
Multi-model llama-server router
     │
     ├── Qwen3-14B Q5_K_M
     │      &quot;&lt;b&gt;fast&lt;/b&gt;&quot;
     │
     └── Qwen3-Coder-30B-A3B Q4_K_M
            &quot;&lt;b&gt;coder&lt;/b&gt;&quot;
     │
     ▼
OpenAI-compatible API
     │
     ├── Browser UI
     ├── Python
     ├── C#
     ├── agents
     └── other machines on the LAN
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The server now starts automatically after a reboot and exposes both models through one endpoint.&lt;/p&gt;&lt;p&gt;This post documents the complete process, including the failures along the way.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;1. Starting with &lt;code inline=&quot;&quot;&gt;llmfit&lt;/code&gt;&lt;/h1&gt;&lt;p&gt;I first used &lt;code inline=&quot;&quot;&gt;llmfit&lt;/code&gt; to work out what models were theoretically capable of running on the machine.&lt;/p&gt;&lt;p&gt;It detected roughly:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;CPU: AMD Ryzen 5 7430U
RAM: ~31 GB
GPU: AMD Radeon Graphics
Backend: Vulkan
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The important discovery was that although Windows initially reported only around:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;0.5 GB VRAM
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;this was misleading.&lt;/p&gt;&lt;p&gt;The Radeon is an integrated GPU using &lt;strong&gt;Unified Memory Architecture (UMA)&lt;/strong&gt;, meaning it can borrow system memory.&lt;/p&gt;&lt;p&gt;After installing llama.cpp, this became much clearer:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;llama-cli.exe --list-devices
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;returned:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Available devices:
  Vulkan0: AMD Radeon (TM) Graphics (16345 MiB, 15527 MiB free)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So Vulkan could address approximately &lt;strong&gt;16 GB of shared GPU memory&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;That dramatically changed what models were practical.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;2. Why llama.cpp instead of Ollama&lt;/h1&gt;&lt;p&gt;Ollama is excellent for convenience, but I wanted lower-level control over:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;GPU layer offloading&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Vulkan&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;context size&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;batch size&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;micro-batch size&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;KV-cache placement&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;memory allocation&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;model quantization&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;multi-model routing&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;code inline=&quot;&quot;&gt;llama.cpp&lt;/code&gt; also provides an &lt;strong&gt;OpenAI-compatible API&lt;/strong&gt;, so applications do not need to be coupled to a llama.cpp-specific protocol.&lt;/p&gt;&lt;p&gt;The resulting architecture is:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;GGUF
 ↓
llama.cpp
 ↓
llama-server
 ↓
/v1/chat/completions
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This means the same client abstractions can later work with:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;OpenAI&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;llama.cpp&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Ollama&#39;s OpenAI compatibility endpoint&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;vLLM&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;LM Studio&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;LocalAI&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;other OpenAI-compatible servers&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr /&gt;&lt;h1&gt;3. Installing llama.cpp on Windows&lt;/h1&gt;&lt;p&gt;There was no need to compile llama.cpp.&lt;/p&gt;&lt;p&gt;I downloaded the official &lt;strong&gt;&lt;a href=&quot;https://github.com/ggml-org/llama.cpp/blob/master/docs/build.md#vulkan&quot;&gt;Windows x64 Vulkan build&lt;/a&gt;&lt;/strong&gt; from the llama.cpp releases.&lt;/p&gt;&lt;p&gt;The relevant package is named approximately:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;llama-bXXXXX-bin-win-vulkan-x64.zip
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I extracted it to:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\llama.cpp
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The directory contained binaries such as:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\llama.cpp\
    llama-cli.exe
    llama-server.exe
    llama-bench.exe
    ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Testing the executable:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-cli.exe --version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;gave:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;version: 0.1.2-dev
build: 10517
commit: dc72703fc
built with Clang 20.1.8 for Windows x86_64
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;4. The first problem: Windows &quot;Bad Image&quot;&lt;/h1&gt;&lt;p&gt;Initially Windows refused to start one of the llama.cpp DLLs with a message similar to:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;llama-cli.exe - Bad Image

Error status 0xC0E90002
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The failing DLL was:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;llama-cli-mtmd.dll
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This turned out not to be a &lt;b&gt;Vulkan &lt;/b&gt;problem.&lt;/p&gt;&lt;p&gt;Windows security controls were blocking one of the unsigned/open-source binaries.&lt;/p&gt;&lt;p&gt;After allowing the application appropriately, this worked:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-cli.exe --version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This was an important distinction.&lt;/p&gt;&lt;p&gt;A true Vulkan failure would more likely produce something such as:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;VK_ERROR_...
failed to load Vulkan backend
no Vulkan devices found
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Instead, Windows had been stopping the process before Vulkan initialization even happened.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;5. Confirming Vulkan actually worked&lt;/h1&gt;&lt;p&gt;The definitive test was:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-cli.exe --list-devices
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Output:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Available devices:
  Vulkan0: AMD Radeon (TM) Graphics (16345 MiB, 15527 MiB free)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At that point I knew:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;the Vulkan llama.cpp build worked;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;the AMD driver worked;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;llama.cpp could see the Radeon;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;approximately 15.5 GB could potentially be allocated by Vulkan.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr /&gt;&lt;h1&gt;6. Choosing the first model&lt;/h1&gt;&lt;p&gt;The first model I tested was:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;a href=&quot;https://huggingface.co/Qwen/Qwen3-Coder-30B-A3B-Instruct&quot;&gt;Qwen3-Coder-30B-A3B-Instruct&lt;/a&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;using:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Q4_K_M
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;quantization.&lt;/p&gt;&lt;p&gt;The file was approximately:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;18.6 GB
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and was stored as:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\models\Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The model uses a Mixture-of-Experts architecture, which made it particularly interesting for relatively modest hardware.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;7. Hugging Face SSL problems&lt;/h1&gt;&lt;p&gt;Initially I tried letting llama.cpp download the model directly:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;llama-cli.exe -hf lmstudio-community/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Instead I received:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;HTTPLIB failed:
SSL server verification failed

error:
--model is required
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The second error was just a consequence of the first: llama.cpp failed to download anything and therefore had no model to load.&lt;/p&gt;&lt;p&gt;Rather than waste time debugging Windows certificate handling, I downloaded the GGUF manually.&lt;/p&gt;&lt;p&gt;The resulting structure was:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\
├── llama.cpp\
│   ├── llama-cli.exe
│   ├── llama-server.exe
│   └── ...
│
└── models\
    └── Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I actually prefer this arrangement for a server.&lt;/p&gt;&lt;p&gt;Once downloaded, inference no longer depends on:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Internet connectivity&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Hugging Face&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;SSL certificates&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;authentication&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;external availability&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr /&gt;&lt;h1&gt;8. The first GPU memory failure&lt;/h1&gt;&lt;p&gt;I initially tried maximum GPU offloading:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-cli.exe ^
  -m C:\models\Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf ^
  -c 8192 ^
  -ngl 99 ^
  -p &quot;Write a high performance C# lock-free ring buffer&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This failed with:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;ggml_vulkan:
Device memory allocation failed

vk::Device::allocateMemory:
ErrorOutOfDeviceMemory
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This made sense.&lt;/p&gt;&lt;p&gt;The model itself was approximately:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;18.6 GB
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;while Vulkan could address around:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;15.5 GB
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and Vulkan also needs memory for:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;compute buffers&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;KV cache&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;staging buffers&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;runtime allocations&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;graph execution&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Windows/WDDM allocations&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So &lt;code inline=&quot;&quot;&gt;-ngl 99&lt;/code&gt; was too aggressive.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;9. Partial GPU offloading&lt;/h1&gt;&lt;p&gt;I next tried:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;-ngl 20
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;with a smaller 4K context:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-cli.exe ^
  -m C:\models\Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf ^
  -c 4096 ^
  -ngl 20 ^
  -p &quot;Write a high performance C# lock-free ring buffer&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This got further, but failed while creating the compute buffers:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;failed to allocate Vulkan0 buffer
failed to allocate compute pp buffers
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The allocation that failed was only around:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;228 MB
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which showed how close the machine was to its Vulkan memory ceiling.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;10. Reducing batch and micro-batch sizes&lt;/h1&gt;&lt;p&gt;The eventual working configuration was:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-cli.exe ^
  -m C:\models\Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf ^
  -c 4096 ^
  -ngl 10 ^
  -b 128 ^
  -ub 128 ^
  --no-kv-offload ^
  -p &quot;Write a high performance C# lock-free ring buffer&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or on one line:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-cli.exe -m C:\models\Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf -c 4096 -ngl 10 -b 128 -ub 128 --no-kv-offload -p &quot;Write a high performance C# lock-free ring buffer&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This worked.&lt;/p&gt;&lt;p&gt;The important settings were:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-c 4096
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4,096-token context.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-ngl 10
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Only ten model layers were explicitly offloaded to Vulkan.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-b 128
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Small prompt-processing batch.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-ub 128
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Small micro-batch.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;--no-kv-offload
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Keep the KV cache out of the already-constrained Vulkan allocation.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;11. First benchmark&lt;/h1&gt;&lt;p&gt;The model produced approximately:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Prompt:     14.6 tokens/s
Generation: 4.6 tokens/s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The UI later showed approximately:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;4.8 tokens/s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;for generation.&lt;/p&gt;&lt;p&gt;That is not particularly fast, but it is entirely usable for a 30B-class coding model running on a low-power Ryzen APU.&lt;/p&gt;&lt;p&gt;The main limitation is memory bandwidth.&lt;/p&gt;&lt;p&gt;The architecture looks roughly like this:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;             32 GB DDR RAM
                   │
          ┌────────┴────────┐
          │                 │
     Ryzen CPU         Radeon iGPU
          │                 │
          └────────┬────────┘
                   │
             Same memory bus
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unlike a discrete GPU, the Radeon does not have hundreds of GB/s or ~1 TB/s of dedicated VRAM bandwidth.&lt;/p&gt;&lt;p&gt;Both CPU and GPU are competing for system-memory bandwidth.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;12. Starting the browser UI&lt;/h1&gt;&lt;p&gt;Once command-line inference worked, the next step was &lt;code inline=&quot;&quot;&gt;llama-server.exe&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;I used:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-server.exe ^
  -m C:\models\Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf ^
  -c 4096 ^
  -ngl 10 ^
  -b 128 ^
  -ub 128 ^
  --no-kv-offload ^
  --host 127.0.0.1 ^
  --port 8080
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then I opened:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:8080
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and the built-in llama.cpp chat UI appeared.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhLo4qsNurYCLVccLnmSowhmfHUVXehdxg13uei8nac1H2WNe7AC7CvEJqQT7lYvPrBVEG6hYO2NTLjTsYU0MGDfXhtMs1Z_uI0XLZSVwa_jFI3umqMhZLuNc_E39YBvbT3jA3zm9-vwMC4OMFaLF1hZYpqa8E-ewrfeXEIENAXXgpjbu49LZCxTx7NvNc&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;953&quot; data-original-width=&quot;990&quot; height=&quot;386&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhLo4qsNurYCLVccLnmSowhmfHUVXehdxg13uei8nac1H2WNe7AC7CvEJqQT7lYvPrBVEG6hYO2NTLjTsYU0MGDfXhtMs1Z_uI0XLZSVwa_jFI3umqMhZLuNc_E39YBvbT3jA3zm9-vwMC4OMFaLF1hZYpqa8E-ewrfeXEIENAXXgpjbu49LZCxTx7NvNc=w400-h386&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;At the same time, the OpenAI-compatible API became available under:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:8080/v1
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;13. Calling the local model from Python&lt;/h1&gt;&lt;p&gt;Because llama.cpp exposes OpenAI-compatible endpoints, the normal OpenAI Python client can be used.&lt;/p&gt;&lt;p&gt;For example:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from openai import OpenAI

client = OpenAI(
    base_url=&quot;http://127.0.0.1:8080/v1&quot;,
    api_key=&quot;local&quot;
)

response = client.chat.completions.create(
    model=&quot;local&quot;,
    messages=[
        {
            &quot;role&quot;: &quot;user&quot;,
            &quot;content&quot;: &quot;Write a C# bounded concurrent queue.&quot;
        }
    ]
)

print(response.choices[0].message.content)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The application does not need to know much about the underlying inference engine.&lt;/p&gt;&lt;p&gt;Conceptually:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Application
    │
    │ OpenAI API
    ▼
localhost:8080/v1
    │
    ▼
llama-server
    │
    ▼
Qwen GGUF
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;14. The context-size problem&lt;/h1&gt;&lt;p&gt;Eventually the UI produced:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;request (7166 tokens) exceeds the available context size (4096 tokens)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This happened because the server was started with:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-c 4096
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and the conversation had grown beyond that.&lt;/p&gt;&lt;p&gt;A context contains more than just the latest user message:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;system prompt
+
previous user messages
+
previous assistant responses
+
new request
+
generated response
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A larger context can be configured, for example:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-c 8192
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-c 12288
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-c 16384
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;but larger context windows have costs:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;larger KV cache&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;more RAM&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;slower prompt processing&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;longer cold-context ingestion&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;On this machine, a &lt;strong&gt;roughly 8K–16K context&lt;/strong&gt; is far more sensible than chasing enormous theoretical context windows.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;15. Adding a faster model&lt;/h1&gt;&lt;p&gt;The 30B coding model worked, but approximately:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;4.8 tokens/s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;is slow for everyday interactive use.&lt;/p&gt;&lt;p&gt;So I added:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;a href=&quot;https://huggingface.co/Qwen/Qwen3-14B&quot;&gt;Qwen3-14B&lt;/a&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;using:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Q5_K_M
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;quantization.&lt;/p&gt;&lt;p&gt;The second model became:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\models\Qwen3-14B-Q5_K_M.gguf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The final model directory was therefore:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\models\
├── Qwen3-14B-Q5_K_M.gguf
└── Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The idea was:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Qwen3-14B
    ↓
fast/default work

Qwen3-Coder-30B
    ↓
harder coding work
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;16. Multi-model routing&lt;/h1&gt;&lt;p&gt;I did not want two permanent &lt;code inline=&quot;&quot;&gt;llama-server.exe&lt;/code&gt; processes consuming RAM simultaneously.&lt;/p&gt;&lt;p&gt;Instead, llama.cpp supports &lt;strong&gt;model presets and routing&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;The goal was:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;                  llama-server
                       │
                --models-max 1
                       │
          ┌────────────┴────────────┐
          │                         │
       &quot;fast&quot;                    &quot;coder&quot;
     Qwen3-14B              Qwen3-Coder-30B
          │                         │
          └────────────┬────────────┘
                       │
              only one loaded
                 at a time
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That is exactly what a 32 GB machine needs.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;17. Creating &lt;code inline=&quot;&quot;&gt;models.ini&lt;/code&gt;&lt;/h1&gt;&lt;p&gt;I created:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\llama.cpp\models.ini
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;with:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;version = 1

[*]
parallel = 1
jinja = true
cache-prompt = true

[fast]
model = C:/models/Qwen3-14B-Q5_K_M.gguf
ctx-size = 8192
n-gpu-layers = 99
batch-size = 128
ubatch-size = 128
no-kv-offload = true
load-on-startup = true

[coder]
model = C:/models/Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf
ctx-size = 8192
n-gpu-layers = 10
batch-size = 128
ubatch-size = 128
no-kv-offload = true
load-on-startup = false
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The names:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;[fast]
[coder]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;become model aliases.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;18. Another mistake: unsupported &lt;code inline=&quot;&quot;&gt;default-model&lt;/code&gt;&lt;/h1&gt;&lt;p&gt;Initially the configuration contained:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;default-model = true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;under the fast model.&lt;/p&gt;&lt;p&gt;The server failed with:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;failed to initialize router models:
option &#39;default-model&#39; not recognized in preset &#39;fast&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That option was not supported by the llama.cpp build I was using.&lt;/p&gt;&lt;p&gt;Removing it solved the issue.&lt;/p&gt;&lt;p&gt;The important startup option was instead:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;load-on-startup = true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;for the &lt;code inline=&quot;&quot;&gt;fast&lt;/code&gt; model.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;19. Starting the multi-model router&lt;/h1&gt;&lt;p&gt;The router was started using:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-server.exe ^
  --models-preset C:\llama.cpp\models.ini ^
  --models-max 1 ^
  --host 127.0.0.1 ^
  --port 8080
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The critical option is:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;--models-max 1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Without it, multiple models might remain loaded simultaneously.&lt;/p&gt;&lt;p&gt;That would be a bad idea with:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;~10 GB 14B model
+
~19 GB 30B model
+
Windows
+
KV caches
+
compute buffers
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With a one-model limit, llama.cpp can effectively behave like:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;request model=&quot;fast&quot;
        ↓
load fast

request model=&quot;coder&quot;
        ↓
unload fast
        ↓
load coder
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The load transition takes time, but RAM remains manageable.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;20. Calling different models through the same API&lt;/h1&gt;&lt;p&gt;Now one server can serve both models.&lt;/p&gt;&lt;p&gt;The base endpoint remains:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:8080/v1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For normal work:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;response = client.chat.completions.create(
    model=&quot;fast&quot;,
    messages=[
        {
            &quot;role&quot;: &quot;user&quot;,
            &quot;content&quot;: &quot;Explain async iterators in C#.&quot;
        }
    ]
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For harder coding tasks:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;response = client.chat.completions.create(
    model=&quot;coder&quot;,
    messages=[
        {
            &quot;role&quot;: &quot;user&quot;,
            &quot;content&quot;: &quot;&quot;&quot;
            Review this MPMC queue implementation for
            memory-ordering and publication bugs.
            &quot;&quot;&quot;
        }
    ]
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Same API.&lt;/p&gt;&lt;p&gt;Different backend model.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;21. Making the server accessible over the LAN&lt;/h1&gt;&lt;p&gt;For access from other machines, I changed:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;--host 127.0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;--host 0.0.0.0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The resulting server command became approximately:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-server.exe ^
  --models-preset C:\llama.cpp\models.ini ^
  --models-max 1 ^
  --sleep-idle-seconds 600 ^
  --host 0.0.0.0 ^
  --port 8080
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now another machine could use:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;http://SERVER-NAME:8080
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, the final browser UI was reachable using the Windows hostname directly:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;http://win-2nsdp31hmq3:8080&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiORzYt2yldkB23KRYvv_Lheb7c1LRNjp4Qm7RSIIpnHPi5fK_rKGcyzZP5_sF3JYIxufMhcm-rT1uXCbPmSsSdtBA3F1BeAAeEuSuAe3fW4is_yVoQomOfPW-hLNwZfU6jPDD8IWPOxobRs8-TnUrvO0eC_HCb7njeYVjz3IVBOxTUvZv4_KTGsbEVg4U&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;460&quot; data-original-width=&quot;1506&quot; height=&quot;195&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiORzYt2yldkB23KRYvv_Lheb7c1LRNjp4Qm7RSIIpnHPi5fK_rKGcyzZP5_sF3JYIxufMhcm-rT1uXCbPmSsSdtBA3F1BeAAeEuSuAe3fW4is_yVoQomOfPW-hLNwZfU6jPDD8IWPOxobRs8-TnUrvO0eC_HCb7njeYVjz3IVBOxTUvZv4_KTGsbEVg4U=w640-h195&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;22. Windows Firewall got in the way&lt;/h1&gt;&lt;p&gt;During unattended startup, I eventually discovered another issue.&lt;/p&gt;&lt;p&gt;Windows displayed:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Do you want to allow public and private networks
to access this app?

llama-server.exe
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This explained why startup appeared to fail.&lt;/p&gt;&lt;p&gt;The process was waiting for an &lt;strong&gt;interactive firewall decision&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;When no user was logged in, nobody could click the dialog.&lt;/p&gt;&lt;p&gt;For a LAN-accessible server, the cleaner solution is a narrow Windows Firewall rule.&lt;/p&gt;&lt;p&gt;From elevated PowerShell:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;New-NetFirewallRule `
  -DisplayName &quot;llama.cpp API - Private LAN&quot; `
  -Direction Inbound `
  -Program &quot;C:\llama.cpp\llama-server.exe&quot; `
  -Protocol TCP `
  -LocalPort 8080 `
  -RemoteAddress LocalSubnet `
  -Profile Private `
  -Action Allow
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This permits:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;llama-server.exe
TCP 8080
Private profile
Local subnet
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;rather than allowing arbitrary public-network access.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;23. Making llama.cpp start after reboot&lt;/h1&gt;&lt;p&gt;Initially I tried a Task Scheduler trigger:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;At startup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;but this was unreliable.&lt;/p&gt;&lt;p&gt;The machine also runs Docker Desktop, which normally expects an actual Windows user session.&lt;/p&gt;&lt;p&gt;There is also a practical issue with running GPU/Vulkan applications in a non-interactive Windows session.&lt;/p&gt;&lt;p&gt;The eventual solution was:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;reboot
   ↓
automatic Windows login
   ↓
interactive desktop session created
   ↓
Docker Desktop starts
   ↓
llama.cpp starts
   ↓
workstation locks
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This has proved much more reliable.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;24. Windows automatic logon&lt;/h1&gt;&lt;p&gt;For automatic logon I used Microsoft&#39;s Sysinternals &lt;strong&gt;Autologon&lt;/strong&gt; utility rather than manually storing a plaintext password in Winlogon registry keys.&lt;/p&gt;&lt;p&gt;After enabling automatic logon for the server account:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Windows boots
      ↓
user automatically logs in
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This creates the normal user session required by the software stack.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;25. Starting llama.cpp at logon&lt;/h1&gt;&lt;p&gt;Instead of:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;At startup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I changed the llama.cpp Task Scheduler trigger to:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;At log on
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;for the server user.&lt;/p&gt;&lt;p&gt;I also added a short delay so Windows, networking and the graphics stack could initialize first.&lt;/p&gt;&lt;p&gt;Approximately:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;At log on
Delay: 30 seconds
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The task runs:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\llama.cpp\start-router.cmd
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;26. The final startup script&lt;/h1&gt;&lt;p&gt;The launcher is approximately:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-bat&quot;&gt;@echo off

cd /d C:\llama.cpp

echo ============================================== &amp;gt;&amp;gt; C:\llama.cpp\llama-server.log
echo Starting llama.cpp at %date% %time% &amp;gt;&amp;gt; C:\llama.cpp\llama-server.log
echo ============================================== &amp;gt;&amp;gt; C:\llama.cpp\llama-server.log

C:\llama.cpp\llama-server.exe ^
  --models-preset C:\llama.cpp\models.ini ^
  --models-max 1 ^
  --sleep-idle-seconds 600 ^
  --host 0.0.0.0 ^
  --port 8080 ^
  &amp;gt;&amp;gt; C:\llama.cpp\llama-server.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This gives me a persistent log:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\llama.cpp\llama-server.log
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which is very useful for diagnosing unattended-startup problems.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;27. Automatically locking the workstation&lt;/h1&gt;&lt;p&gt;Automatic login would otherwise leave the machine unlocked.&lt;/p&gt;&lt;p&gt;So after login and startup I schedule:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;rundll32.exe
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;with:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;user32.dll,LockWorkStation
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;after a short delay.&lt;/p&gt;&lt;p&gt;The resulting sequence is:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Machine reboots
       ↓
Windows boots
       ↓
Automatic login
       ↓
AMD/Vulkan session initialized
       ↓
Docker Desktop starts
       ↓
llama.cpp router starts
       ↓
Firewall already configured
       ↓
Windows locks
       ↓
Services remain running
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Locking is important.&lt;/p&gt;&lt;p&gt;It preserves the logged-in session; logging out would terminate processes belonging to that user.&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;28. The final architecture&lt;/h1&gt;&lt;p&gt;The finished environment looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;                    WINDOWS MACHINE
                           │
                           ▼
                    automatic login
                           │
              ┌────────────┴────────────┐
              │                         │
       Docker Desktop             llama.cpp
                                        │
                                        ▼
                                llama-server router
                                   port 8080
                                        │
                               --models-max 1
                                        │
                   ┌────────────────────┴────────────────────┐
                   │                                         │
                   ▼                                         ▼
             fast                                       coder
        Qwen3-14B Q5_K_M                    Qwen3-Coder-30B-A3B
             ~10 GB                                 ~18.6 GB
          full/large GPU                         partial Vulkan
            offload                                 offload
                   │                                         │
                   └────────────────────┬────────────────────┘
                                        │
                                ONE MODEL AT A TIME
                                        │
                     ┌──────────────────┼──────────────────┐
                     │                  │                  │
                     ▼                  ▼                  ▼
                  Web UI             Python               C#
                     │                  │                  │
                     └──────────────────┼──────────────────┘
                                        │
                              OpenAI-compatible API
                                        │
                         http://SERVER:8080/v1
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;29. What I learned&lt;/h1&gt;&lt;h2&gt;Integrated GPUs are more useful than the VRAM number suggests&lt;/h2&gt;&lt;p&gt;Windows initially showed roughly:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;512 MB dedicated VRAM
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which sounded hopeless.&lt;/p&gt;&lt;p&gt;But Vulkan reported:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;~16 GB accessible GPU memory
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;because the Radeon uses shared system RAM.&lt;/p&gt;&lt;p&gt;That made reasonably large models practical.&lt;/p&gt;&lt;hr /&gt;&lt;h2&gt;Shared memory is not extra memory&lt;/h2&gt;&lt;p&gt;The machine does &lt;strong&gt;not&lt;/strong&gt; have:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;32 GB system RAM
+
16 GB VRAM
=
48 GB
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It has:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;32 GB physical RAM
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;shared between:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Windows&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;CPU inference&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;GPU inference&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;KV cache&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;compute buffers&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;other applications&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The 16 GB figure is effectively a GPU allocation budget over the same physical memory.&lt;/p&gt;&lt;hr /&gt;&lt;h2&gt;Maximum GPU offload is not necessarily optimal&lt;/h2&gt;&lt;p&gt;For the 30B model:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-ngl 99
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;failed.&lt;/p&gt;&lt;p&gt;Even:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-ngl 20
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;eventually exhausted Vulkan compute-buffer memory.&lt;/p&gt;&lt;p&gt;The stable configuration became:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-ngl 10
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There is little value in maximizing GPU layers if doing so makes the system unstable.&lt;/p&gt;&lt;hr /&gt;&lt;h2&gt;Batch size matters enormously&lt;/h2&gt;&lt;p&gt;Reducing:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-b
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;-ub
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;made the difference between failure and successful inference.&lt;/p&gt;&lt;p&gt;For interactive use, giant prompt-processing batches are unnecessary.&lt;/p&gt;&lt;hr /&gt;&lt;h2&gt;Keep enough memory for runtime buffers&lt;/h2&gt;&lt;p&gt;A model fitting &lt;em&gt;numerically&lt;/em&gt; into GPU memory does not imply it will run.&lt;/p&gt;&lt;p&gt;You also need room for:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;model tensors
+
KV cache
+
compute buffers
+
graph buffers
+
Vulkan overhead
+
Windows/WDDM
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Always leave headroom.&lt;/p&gt;&lt;hr /&gt;&lt;h2&gt;Large context windows are expensive&lt;/h2&gt;&lt;p&gt;A model may advertise huge context sizes, but hardware reality matters more.&lt;/p&gt;&lt;p&gt;On this machine:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;8K–16K
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;is far more useful than trying to force:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;32K
64K
128K
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;contexts into memory.&lt;/p&gt;&lt;p&gt;Prompt processing also becomes increasingly expensive as conversations grow.&lt;/p&gt;&lt;hr /&gt;&lt;h2&gt;A smaller model can be a better default&lt;/h2&gt;&lt;p&gt;The 30B model gives better quality on harder tasks, but around:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;4.8 tokens/s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;is not ideal for every interaction.&lt;/p&gt;&lt;p&gt;Using a smaller model for everyday work and escalating difficult requests to a larger model is a better architecture.&lt;/p&gt;&lt;p&gt;Hence:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;fast
  ↓
Qwen3-14B

coder
  ↓
Qwen3-Coder-30B
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;30. Current model configuration&lt;/h1&gt;&lt;p&gt;The final &lt;code inline=&quot;&quot;&gt;models.ini&lt;/code&gt; is:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;version = 1

[*]
parallel = 1
jinja = true
cache-prompt = true

[fast]
model = C:/models/Qwen3-14B-Q5_K_M.gguf
ctx-size = 8192
n-gpu-layers = 99
batch-size = 128
ubatch-size = 128
no-kv-offload = true
load-on-startup = true

[coder]
model = C:/models/Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf
ctx-size = 8192
n-gpu-layers = 10
batch-size = 128
ubatch-size = 128
no-kv-offload = true
load-on-startup = false
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And the router starts with:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;C:\llama.cpp\llama-server.exe ^
  --models-preset C:\llama.cpp\models.ini ^
  --models-max 1 ^
  --sleep-idle-seconds 600 ^
  --host 0.0.0.0 ^
  --port 8080
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;31. Testing the server&lt;/h1&gt;&lt;p&gt;Local health check:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;curl http://127.0.0.1:8080/health
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Model list:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;curl http://127.0.0.1:8080/v1/models
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;From another machine:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;curl http://SERVER-NAME:8080/health
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Browser:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;http://SERVER-NAME:8080
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;API:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;http://SERVER-NAME:8080/v1
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;32. OpenAI-compatible Python example&lt;/h1&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from openai import OpenAI

client = OpenAI(
    base_url=&quot;http://SERVER-NAME:8080/v1&quot;,
    api_key=&quot;local&quot;
)

response = client.chat.completions.create(
    model=&quot;fast&quot;,
    messages=[
        {
            &quot;role&quot;: &quot;system&quot;,
            &quot;content&quot;: &quot;You are an experienced software engineer.&quot;
        },
        {
            &quot;role&quot;: &quot;user&quot;,
            &quot;content&quot;: &quot;Explain the LMAX Disruptor architecture.&quot;
        }
    ]
)

print(response.choices[0].message.content)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For the larger model:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;response = client.chat.completions.create(
    model=&quot;coder&quot;,
    messages=[
        {
            &quot;role&quot;: &quot;user&quot;,
            &quot;content&quot;: &quot;&quot;&quot;
            Design a bounded lock-free MPMC queue in C#.
            Discuss memory ordering, ABA issues and false sharing.
            &quot;&quot;&quot;
        }
    ]
)
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;33. What I would improve next&lt;/h1&gt;&lt;p&gt;There are several obvious next steps.&lt;/p&gt;&lt;h2&gt;API authentication&lt;/h2&gt;&lt;p&gt;For anything beyond a trusted local machine, add:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;--api-key
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and never expose port &lt;code inline=&quot;&quot;&gt;8080&lt;/code&gt; directly to the public Internet.&lt;/p&gt;&lt;hr /&gt;&lt;h2&gt;Tailscale&lt;/h2&gt;&lt;p&gt;For remote access away from home, I would use:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Laptop
   │
Tailscale
   │
Home LLM server
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;rather than router port forwarding.&lt;/p&gt;&lt;hr /&gt;&lt;h2&gt;Open WebUI&lt;/h2&gt;&lt;p&gt;llama.cpp&#39;s native UI is already surprisingly usable.&lt;/p&gt;&lt;p&gt;A future enhancement could be:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Open WebUI
    ↓
llama.cpp /v1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;for richer:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;conversation management&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;file handling&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;RAG&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;authentication&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;multiple users&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;persistent histories&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr /&gt;&lt;h2&gt;A genuinely fast small model&lt;/h2&gt;&lt;p&gt;I may also add a third model in the 7B–8B range:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;fastest
    ↓
7B model
    ↓
quick tasks / summarization / simple coding
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;leaving:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;14B
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;for normal work and:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;30B
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;for difficult coding/reasoning.&lt;/p&gt;&lt;p&gt;That would effectively create three local inference tiers:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;FASTEST
7B
 ↓
cheap/simple work

FAST
14B
 ↓
default

QUALITY
30B
 ↓
hard problems
&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;&lt;h1&gt;34. Final result&lt;/h1&gt;&lt;p&gt;What started as a modest Windows machine with an integrated Radeon GPU has become a completely private LLM inference server.&lt;/p&gt;&lt;p&gt;It now provides:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;local inference;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;no per-token fees;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;no external inference API;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;no model prompts leaving the machine;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;AMD GPU acceleration through Vulkan;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;multiple GGUF models;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;automatic model routing;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;an OpenAI-compatible REST API;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;a browser-based chat interface;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;LAN access;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;automatic startup after reboot;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Docker running alongside it;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;and unattended operation.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The most surprising part was that the hardware was substantially more capable than its specification initially suggested.&lt;/p&gt;&lt;p&gt;The key was not trying to force desktop-GPU assumptions onto an integrated Radeon.&lt;/p&gt;&lt;p&gt;Instead, the working solution used:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Vulkan
+
shared GPU memory
+
partial model offload
+
small batches
+
CPU-side KV cache
+
quantized GGUF models
+
dynamic model routing
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The end result is not going to compete with a high-end NVIDIA inference server.&lt;/p&gt;&lt;p&gt;It does not need to.&lt;/p&gt;&lt;p&gt;For private coding, experimentation, agents, document processing and local application integration, it is already a remarkably capable little LLM server sitting on hardware that was available anyway.&lt;/p&gt;&lt;p&gt;And, perhaps most importantly:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;The API is mine.
The models are mine.
The data stays local.
&lt;/code&gt;&lt;/pre&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/08/building-private-local-llm-server-on.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCFcQwi3mpysRQ5-UxPFha61OHb95WFausBnsIxdwNPFxDEIO1noo-HkoybQybppY97AFbKzj6BQkpfLwe6On4no0gnTIcXxH0AFGUhc54GXfd6fG7NPYHLHq0YPXbniXflHqkKIasq0sUqtvW-cDnMezT60E2sIo6dJp04NrM4kqJewtKpzWJjRtokrQ/s72-c/ChatGPT%20Image%20Aug%2024,%202026,%2008_12_37%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-4193367191106643324</guid><pubDate>Sat, 01 Aug 2026 18:49:01 +0000</pubDate><atom:updated>2026-08-01T18:49:01.097+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">competition</category><category domain="http://www.blogger.com/atom/ns#">kaggle</category><category domain="http://www.blogger.com/atom/ns#">Machine Learning</category><title>From 1,880th to 8th: A Six-Day, Validation-First Kaggle Sprint</title><description>&lt;h2 style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp2i6eaBWGrWUhItZNTvVLVVa4podz2y415rimfKpibO25cByLQlmBwPgQOxXjVhmE-bqXTs2HYRKDNe3iVW_8cMGnRpWU7dXE3fU8PWQpQxRp0dSXAgOaNfu0mhhVMYFF8fQ2CWyyjA_uCghQm8ZDBXbmdKmZZp4vuGkDHdn51qtz-5qvQdFpemd-W7Y/s1536/ChatGPT%20Image%20Aug%201,%202026,%2007_35_51%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp2i6eaBWGrWUhItZNTvVLVVa4podz2y415rimfKpibO25cByLQlmBwPgQOxXjVhmE-bqXTs2HYRKDNe3iVW_8cMGnRpWU7dXE3fU8PWQpQxRp0dSXAgOaNfu0mhhVMYFF8fQ2CWyyjA_uCghQm8ZDBXbmdKmZZp4vuGkDHdn51qtz-5qvQdFpemd-W7Y/s320/ChatGPT%20Image%20Aug%201,%202026,%2007_35_51%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;From 1,880th to 8th: A Six-Day, Validation-First Kaggle Sprint&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;2&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;em&gt;How a disciplined experiment framework, leakage-safe target statistics, class-aware decision rules, and a GPU-trained FT-Transformer produced an 8th-place private leader board finish in Playground Series S6E7.&lt;/em&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; id=&quot;the-result&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;br /&gt;The result&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;I finished Kaggle&#39;s &lt;strong&gt;Playground Series S6E7: Predicting Student Health Risk&lt;/strong&gt; at &lt;strong&gt;8th on the private leaderboard&lt;/strong&gt; and &lt;strong&gt;63rd on the public leaderboard&lt;/strong&gt;, out of &lt;strong&gt;3,356 teams&lt;/strong&gt;.&lt;/p&gt;&lt;table class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;border-collapse: collapse; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em;&quot;&gt;&lt;thead class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot;&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Result&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Rank&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Score&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Approximate percentile&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Final private leaderboard&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;strong&gt;8 / 3,356&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;strong&gt;0.95084&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;strong&gt;Top 0.24%&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;15&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Final public leaderboard&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;strong&gt;63 / 3,356&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;strong&gt;0.95306&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;strong&gt;Top 1.88%&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The first repository commit was made on 26 July 2026. The final public submission landed on 31 July, less than five hours before the deadline. In roughly five and a half days, I recorded &lt;strong&gt;161 completed experiments across 28 model and ensemble families&lt;/strong&gt; and made &lt;strong&gt;10 scoring Kaggle submissions&lt;/strong&gt;.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;22&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The headline is exciting, but the most useful part of the story is the distinction between the two final scores:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot;&gt;The &lt;strong&gt;private score of 0.95084&lt;/strong&gt;, which produced the 8th-place finish, came from the independently trained FT-Transformer pipeline. This is the result that best represents model generalization.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot;&gt;The &lt;strong&gt;public score of 0.95306&lt;/strong&gt; came from a late, leaderboard-guided 29-row cleanup of a public 0.95303 anchor. That artifact scored only 0.95018 privately. It was a legitimate, reproducible competition experiment, but it was not a universal model improvement and it clearly overfit the 20% public split.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;33&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That separation matters. The public leader board rewarded the final clean-up; &lt;i&gt;the private leader board rewarded the model.&lt;/i&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; id=&quot;the-competition-in-one-page&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;The competition in one page&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The task was a &lt;b&gt;three-class &lt;/b&gt;classification problem. For every test row, the model had to predict one of:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;41&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;41&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;at-risk&lt;/code&gt;;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;fit&lt;/code&gt;;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;43&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;unhealthy&lt;/code&gt;.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;45&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The training set contained &lt;strong&gt;690,088 rows&lt;/strong&gt;, the test set &lt;strong&gt;295,753 rows&lt;/strong&gt;, and the model received &lt;strong&gt;13 health and behaviour features&lt;/strong&gt;: seven numeric and six categorical. Missingness was part of the problem—there were 449,496 missing training cells, with per-feature missing rates ranging from roughly 1% to 12%.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The class distribution was extremely uneven:&lt;/p&gt;&lt;table class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;border-collapse: collapse; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em;&quot;&gt;&lt;thead class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot;&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Class&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Training rows&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Share&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;at-risk&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;592,561&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;85.87%&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;unhealthy&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;57,724&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;8.36%&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;fit&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;39,803&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;5.77%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;58&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Kaggle evaluated submissions with &lt;strong&gt;balanced accuracy&lt;/strong&gt;, the unweighted mean of the three class recalls:&lt;/p&gt;&lt;p class=&quot;katex-block&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span class=&quot;katex-display&quot; style=&quot;display: block; margin: 1em 0px; text-align: center;&quot;&gt;&lt;span class=&quot;katex&quot; style=&quot;display: block; font-family: KaTeX_Main, &amp;quot;Times New Roman&amp;quot;, serif; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 1.21em; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: 1.2; text-rendering: auto; white-space: nowrap;&quot;&gt;&lt;span class=&quot;katex-mathml&quot; style=&quot;border: 0px; clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;&quot;&gt;&lt;math display=&quot;block&quot; xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;BA&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;/mfrac&gt;&lt;mrow&gt;&lt;mo fence=&quot;true&quot;&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Recall&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;/mrow&gt;&lt;mtext&gt;at-risk&lt;/mtext&gt;&lt;/msub&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Recall&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;/mrow&gt;&lt;mtext&gt;fit&lt;/mtext&gt;&lt;/msub&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;Recall&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;/mrow&gt;&lt;mtext&gt;unhealthy&lt;/mtext&gt;&lt;/msub&gt;&lt;mo fence=&quot;true&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;/mrow&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;katex-html&quot; style=&quot;border-color: currentcolor; display: block; position: relative;&quot;&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;BA&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot; style=&quot;border-color: currentcolor;&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.0074em; vertical-align: -0.686em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mopen nulldelimiter&quot; style=&quot;border-color: currentcolor; display: inline-block; width: 0.12em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 1.3214em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -2.314em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor; display: inline-block;&quot;&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3.23em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;frac-line&quot; style=&quot;border-bottom-style: solid; border-bottom-width: 0.04em; border-color: currentcolor; display: inline-block; min-height: 1px; width: 8.48438px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3.677em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor; display: inline-block;&quot;&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.686em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose nulldelimiter&quot; style=&quot;border-color: currentcolor; display: inline-block; width: 0.12em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;minner&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mopen delimcenter&quot; style=&quot;border-color: currentcolor; position: relative; top: 0em;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mathrm&quot; style=&quot;border-color: currentcolor;&quot;&gt;Recall&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;msupsub&quot; style=&quot;border-color: currentcolor; text-align: left;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.3361em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-right: 0.05em; position: relative; top: -2.55em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.7em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord text mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;at-risk&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.15em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mathrm&quot; style=&quot;border-color: currentcolor;&quot;&gt;Recall&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;msupsub&quot; style=&quot;border-color: currentcolor; text-align: left;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.3361em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-right: 0.05em; position: relative; top: -2.55em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.7em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord text mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;fit&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.15em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mathrm&quot; style=&quot;border-color: currentcolor;&quot;&gt;Recall&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;msupsub&quot; style=&quot;border-color: currentcolor; text-align: left;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.3361em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-right: 0.05em; position: relative; top: -2.55em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.7em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord text mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;unhealthy&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.2861em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose delimcenter&quot; style=&quot;border-color: currentcolor; position: relative; top: 0em;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;70&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That metric changes the strategy completely. A model that predicts the 85.87% majority class for every row has high ordinary accuracy but a balanced accuracy of only one third. The model must recover the two small classes without sacrificing too much majority-class recall.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;75&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The data audit found no duplicate IDs, no exact train/test overlap, and no automatic leakage flags. Adversarial validation did, however, produce an AUC of 0.5850 in the initial audit and 0.6199 with the expanded diagnostic feature set. In other words, train and test were similar, but not interchangeable. That moderate drift was one reason not to trust tiny cross-validation gains or public-leaderboard movement on its own.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;82&quot; dir=&quot;auto&quot; id=&quot;build-the-laboratory-before-chasing-the-score&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Build the laboratory before chasing the score&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;84&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The project started as more than a single notebook. I built a reusable, configuration-driven framework around the competition:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;87&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;87&quot; dir=&quot;auto&quot;&gt;append-only experiment and submission registries;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;88&quot; dir=&quot;auto&quot;&gt;fold-aligned out-of-fold and test probabilities;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;89&quot; dir=&quot;auto&quot;&gt;fold-local feature fitting and target encoding;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;90&quot; dir=&quot;auto&quot;&gt;stratified cross-validation with fixed, reproducible seeds;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;91&quot; dir=&quot;auto&quot;&gt;candidate comparison with fold wins, bootstrap intervals, per-class recall, and disagreement analysis;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;93&quot; dir=&quot;auto&quot;&gt;submission schema, ID-order, label-domain, duplicate, and missing-value checks;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;94&quot; dir=&quot;auto&quot;&gt;SHA-256 hashes for important notebook inputs, probability files, and submissions;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;95&quot; dir=&quot;auto&quot;&gt;guarded upload commands, so training and submission remained separate actions;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot;&gt;unit, integration, lint, formatting, and type-checking gates.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;98&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This investment paid off when the experimentation became frantic. By the last two days, several long-running GPU notebooks were in flight and many candidate scores differed by less than 0.0002. Without stable folds, stored OOF probabilities, and lineage, it would have been impossible to tell a real improvement from noise.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;103&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The promotion rule for a full candidate was deliberately strict. Relative to the verified incumbent, it had to:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;106&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;106&quot; dir=&quot;auto&quot;&gt;improve balanced accuracy by at least &lt;strong&gt;0.00020&lt;/strong&gt;;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;107&quot; dir=&quot;auto&quot;&gt;win at least &lt;strong&gt;five of seven folds&lt;/strong&gt;;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;108&quot; dir=&quot;auto&quot;&gt;avoid reducing any class recall by more than &lt;strong&gt;0.00050&lt;/strong&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;110&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That rule rejected some attractive-looking results—including the best XGBoost/FT blend—and protected the campaign from spending submissions on fragile OOF wins.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;113&quot; dir=&quot;auto&quot; id=&quot;the-path-from-092933-to-095054&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;The path from 0.92933 to 0.95054&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The first scoring model was a five-fold LightGBM baseline. It established that the pipeline worked, but also exposed the central issue: the default probability argmax was optimized for ordinary accuracy, not balanced accuracy.&lt;/p&gt;&lt;table class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot; style=&quot;border-collapse: collapse; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em;&quot;&gt;&lt;thead class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot;&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Milestone&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Honest local OOF BA&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Public score&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Private score&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody class=&quot;code-line&quot; data-line=&quot;121&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;121&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;LightGBM baseline&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.933069&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.92933&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.92979&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;122&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;LightGBM + cross-fitted class decisions&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.939377&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.93520&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.93597&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;123&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;CatStat XGBoost&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.949837&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.95006&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.95031&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;124&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Two-seed XGBoost blend&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.949802&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.94972&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.95012&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;125&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Exact-statistic XGBoost&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.950398&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.95054&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.95027&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;126&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;FT-Transformer v2&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.950549&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.95094&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;strong&gt;0.95084&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;127&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Public-anchor 29-row cleanup&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;not a trained model&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;strong&gt;0.95306&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.95018&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; id=&quot;the-biggest-early-gain-was-the-decision-rule&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;&quot;&gt;The biggest early gain was the decision rule&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;131&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For each class, I added a learned offset to the log probability:&lt;/p&gt;&lt;p class=&quot;katex-block&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span class=&quot;katex-display&quot; style=&quot;display: block; margin: 1em 0px; text-align: center;&quot;&gt;&lt;span class=&quot;katex&quot; style=&quot;display: block; font-family: KaTeX_Main, &amp;quot;Times New Roman&amp;quot;, serif; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 1.21em; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: 1.2; text-rendering: auto; white-space: nowrap;&quot;&gt;&lt;span class=&quot;katex-mathml&quot; style=&quot;border: 0px; clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;&quot;&gt;&lt;math display=&quot;block&quot; xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;^&lt;/mo&gt;&lt;/mover&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;arg&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;munder&gt;&lt;mrow&gt;&lt;mi&gt;max&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;/mrow&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/munder&gt;&lt;mrow&gt;&lt;mo fence=&quot;true&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;log&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;mo fence=&quot;true&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;/mrow&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;katex-html&quot; style=&quot;border-color: currentcolor; display: block; position: relative;&quot;&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 0.8889em; vertical-align: -0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord accent&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.6944em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; display: inline-block; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03588em;&quot;&gt;y&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;accent-body&quot; style=&quot;border-color: currentcolor; display: inline-block; left: -0.1944em; position: relative; width: 0px;&quot;&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.1944em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot; style=&quot;border-color: currentcolor;&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 1.5021em; vertical-align: -0.7521em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;ar&lt;span style=&quot;border-color: currentcolor; margin-right: 0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.4306em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-left: 0em; position: relative; top: -2.3479em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: inline-block;&quot;&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;max&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.7521em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;minner&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mopen delimcenter&quot; style=&quot;border-color: currentcolor; position: relative; top: 0em;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;lo&lt;span style=&quot;border-color: currentcolor; margin-right: 0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic;&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;msupsub&quot; style=&quot;border-color: currentcolor; text-align: left;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.3361em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-left: 0em; margin-right: 0.05em; position: relative; top: -2.55em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.7em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.15em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot; style=&quot;border-color: currentcolor;&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic;&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;msupsub&quot; style=&quot;border-color: currentcolor; text-align: left;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.3361em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-left: 0em; margin-right: 0.05em; position: relative; top: -2.55em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.7em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.15em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose delimcenter&quot; style=&quot;border-color: currentcolor; position: relative; top: 0em;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;137&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The offsets were &lt;strong&gt;cross-fitted&lt;/strong&gt;. When scoring fold&amp;nbsp;&lt;span class=&quot;katex&quot; style=&quot;font-family: KaTeX_Main, &amp;quot;Times New Roman&amp;quot;, serif; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 1.21em; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: 1.2; text-rendering: auto;&quot;&gt;&lt;span class=&quot;katex-mathml&quot; style=&quot;border: 0px; clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;katex-html&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; white-space: nowrap; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 0.8889em; vertical-align: -0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, its offset vector was learned from all other folds, never from the labels being evaluated. A final vector was then fitted on all OOF rows and applied to test predictions.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;141&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;On the LightGBM model, this increased OOF balanced accuracy from 0.933069 to 0.939377 and improved all five folds. On the stronger tree and neural models, the same idea remained the dominant post-processing lever.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;145&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The FT notebook expressed the equivalent intuition as prior correction:&lt;/p&gt;&lt;p class=&quot;katex-block&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span class=&quot;katex-display&quot; style=&quot;display: block; margin: 1em 0px; text-align: center;&quot;&gt;&lt;span class=&quot;katex&quot; style=&quot;display: block; font-family: KaTeX_Main, &amp;quot;Times New Roman&amp;quot;, serif; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 1.21em; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: 1.2; text-rendering: auto; white-space: nowrap;&quot;&gt;&lt;span class=&quot;katex-mathml&quot; style=&quot;border: 0px; clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;&quot;&gt;&lt;math display=&quot;block&quot; xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mover accent=&quot;true&quot;&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;^&lt;/mo&gt;&lt;/mover&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;arg&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;munder&gt;&lt;mrow&gt;&lt;mi&gt;max&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;/mrow&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/munder&gt;&lt;mfrac&gt;&lt;msub&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;msubsup&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/msubsup&gt;&lt;/mfrac&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;/mrow&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;katex-html&quot; style=&quot;border-color: currentcolor; display: block; position: relative;&quot;&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 0.8889em; vertical-align: -0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord accent&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.6944em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; display: inline-block; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03588em;&quot;&gt;y&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;accent-body&quot; style=&quot;border-color: currentcolor; display: inline-block; left: -0.1944em; position: relative; width: 0px;&quot;&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.1944em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot; style=&quot;border-color: currentcolor;&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.2659em; vertical-align: -1.1583em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;ar&lt;span style=&quot;border-color: currentcolor; margin-right: 0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.4306em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-left: 0em; position: relative; top: -2.3479em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: inline-block;&quot;&gt;&lt;span class=&quot;mop&quot; style=&quot;border-color: currentcolor;&quot;&gt;max&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.7521em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;border-color: currentcolor; display: inline-block; margin-right: 0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mopen nulldelimiter&quot; style=&quot;border-color: currentcolor; display: inline-block; width: 0.12em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 1.1076em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -2.143em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor; display: inline-block;&quot;&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;msupsub&quot; style=&quot;border-color: currentcolor; text-align: left;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.967em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-left: -0.0359em; margin-right: 0.05em; position: relative; top: -2.3987em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.7em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-right: 0.05em; position: relative; top: -3.1809em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.7em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mtight&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.3013em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3.23em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;frac-line&quot; style=&quot;border-bottom-style: solid; border-bottom-width: 0.04em; border-color: currentcolor; display: inline-block; min-height: 1px; width: 18.4375px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative; top: -3.677em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 3em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor; display: inline-block;&quot;&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic;&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;msupsub&quot; style=&quot;border-color: currentcolor; text-align: left;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.3361em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-left: 0em; margin-right: 0.05em; position: relative; top: -2.55em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.7em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.15em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 1.1583em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose nulldelimiter&quot; style=&quot;border-color: currentcolor; display: inline-block; width: 0.12em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mpunct&quot; style=&quot;border-color: currentcolor;&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;151&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;where&amp;nbsp;&lt;span class=&quot;katex&quot; style=&quot;font-family: KaTeX_Main, &amp;quot;Times New Roman&amp;quot;, serif; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 1.21em; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: 1.2; text-rendering: auto;&quot;&gt;&lt;span class=&quot;katex-mathml&quot; style=&quot;border: 0px; clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;katex-html&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; white-space: nowrap; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 0.5806em; vertical-align: -0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;msupsub&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot; style=&quot;border-collapse: collapse; border-color: currentcolor; display: inline-table; margin-right: -2px; table-layout: fixed;&quot;&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.3361em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; margin-left: -0.0359em; margin-right: 0.05em; position: relative; top: -2.55em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 2.7em; overflow: hidden; width: 0px;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot; style=&quot;border-color: currentcolor; display: inline-block; font-size: 0.7em;&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot; style=&quot;border-color: currentcolor; display: table-cell; font-size: 1px; min-width: 2px; vertical-align: bottom; width: 2px;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot; style=&quot;border-color: currentcolor; display: table-row;&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;border-color: currentcolor; display: table-cell; height: 0.15em; position: relative; vertical-align: bottom;&quot;&gt;&lt;span style=&quot;border-color: currentcolor; display: block; height: 0px; position: relative;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;is the training prior for class&amp;nbsp;&lt;span class=&quot;katex&quot; style=&quot;font-family: KaTeX_Main, &amp;quot;Times New Roman&amp;quot;, serif; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 1.21em; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: 1.2; text-rendering: auto;&quot;&gt;&lt;span class=&quot;katex-mathml&quot; style=&quot;border: 0px; clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/mrow&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;katex-html&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; white-space: nowrap; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Setting&amp;nbsp;&lt;span class=&quot;katex&quot; style=&quot;font-family: KaTeX_Main, &amp;quot;Times New Roman&amp;quot;, serif; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 1.21em; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: 1.2; text-rendering: auto;&quot;&gt;&lt;span class=&quot;katex-mathml&quot; style=&quot;border: 0px; clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/mrow&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;katex-html&quot; style=&quot;border-color: currentcolor;&quot;&gt;&lt;span class=&quot;base&quot; style=&quot;border-color: currentcolor; display: inline-block; position: relative; white-space: nowrap; width: min-content;&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;border-color: currentcolor; display: inline-block; height: 0.8889em; vertical-align: -0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;border-color: currentcolor; font-family: KaTeX_Math; font-style: italic; margin-right: 0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; near one asks the classifier to behave as if the classes were closer to equally likely, which aligns the decision rule with balanced accuracy.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;155&quot; dir=&quot;auto&quot; id=&quot;exact-values-were-more-informative-than-they-looked&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;&quot;&gt;Exact values were more informative than they looked&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;157&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The next breakthrough was fold-local multiclass target statistics. The data was synthetic, but many numeric values repeated exactly. A value such as a step count or heart rate could therefore behave like a high-cardinality category.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;161&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For each selected feature value, I estimated the conditional class distribution on the training portion of a fold and transformed only the held-out portion. The tree pipeline expanded exact-value statistics across all seven numeric features and three ordinal feature interactions. The enhanced XGBoost model improved every corrected fold over its predecessor and reached 0.950398 honest OOF and 0.95054 public.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;167&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This feature family also taught an expensive lesson: &lt;strong&gt;do not screen a sample-size-dependent encoder only on a small sample&lt;/strong&gt;. Exact numeric target encoding looked weak on tens of thousands of rows and became valuable at 690,088 rows, where repeated values finally had enough support.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;172&quot; dir=&quot;auto&quot; id=&quot;the-model-that-delivered-8th-place-ft-transformer-v2&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;The model that delivered 8th place: FT-Transformer v2&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;174&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Most strong solutions in this competition were tree-based. The final private result came from adding a genuinely different family: an FT-Transformer trained with &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; color: #d7ba7d; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;masamlp&lt;/code&gt; on Kaggle&#39;s T4 GPU.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;178&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The final v2 specification was:&lt;/p&gt;&lt;table class=&quot;code-line&quot; data-line=&quot;180&quot; dir=&quot;auto&quot; style=&quot;border-collapse: collapse; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em;&quot;&gt;&lt;thead class=&quot;code-line&quot; data-line=&quot;180&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;180&quot; dir=&quot;auto&quot;&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Component&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Setting&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody class=&quot;code-line&quot; data-line=&quot;182&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;182&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Outer validation&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;7-fold shuffled StratifiedKFold, seed 42&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;183&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Raw inputs&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;13 competition features&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;184&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Additional inputs&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;39 fold-local exact-value target-statistic features&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;185&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Total model inputs&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;52&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;186&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Categorical handling&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;learned embeddings for six categorical columns&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;187&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Numeric handling&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;quantile scaling and &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;plr-lite&lt;/code&gt; embeddings&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;188&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Transformer&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;128-dimensional blocks, 2 blocks, 8 attention heads&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;189&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Training&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;AdamW, learning rate 0.001, batch size 4,096&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;190&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Schedule&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;cosine, 16 fixed epochs, no early stopping&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;191&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;In-model ensemble&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;4 independently initialized members per fold&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;192&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Test prediction&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;mean probabilities across seven fold models&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;194&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The target encoder was fitted inside every outer training fold. Its training-side values were themselves generated out of fold, while validation and test were only transformed. Quantile scaling, categorical vocabularies, imputation, embeddings, and model weights were also fold-local.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;199&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Fixed epochs were deliberate. Restoring the checkpoint that performed best on the same validation fold would have added roughly 0.0003 of optimistic validation score, not necessarily 0.0003 of generalizable skill.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;203&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The neural model&#39;s raw argmax OOF score was &lt;strong&gt;0.891869&lt;/strong&gt;. After honest cross-fitted decision correction, it reached &lt;strong&gt;0.950549 ± 0.001740&lt;/strong&gt;. It beat the corrected XGBoost incumbent by 0.000151 and won four of seven folds. Its raw probabilities had classwise correlations of 0.9984–0.9988 with XGBoost: similar, but different enough to create useful disagreement.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;209&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Under the predeclared local gate, that was not enough to claim a confirmed standalone improvement: the gain was below 0.00020, only four folds improved, and unhealthy recall fell by 0.000624. Near the deadline, however, the independently trained neural submission was still a rational model-family hedge. The distinction is important: the repository recorded it as a valid full model without overstating the OOF gain.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;215&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The Kaggle notebook submission scored &lt;strong&gt;0.95094 public and 0.95084 private&lt;/strong&gt;. The private score was the best of the campaign and placed the team 8th on the final leaderboard.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;219&quot; dir=&quot;auto&quot; id=&quot;why-the-notebook-infrastructure-mattered&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;&quot;&gt;Why the notebook infrastructure mattered&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;221&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The local full FT run had to be stopped after more than six hours. &lt;b&gt;The RTX 2060 was pinned at full utilization and reached 91°C, while other experiments still needed the machine&lt;/b&gt;. Smaller local FT screens also underestimated the exact-value feature family because they lacked enough rows.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;226&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The practical solution was to move the full neural confirmation to a private Kaggle Notebook, save raw OOF and test probabilities, download them, verify their hashes and row alignment, and import them into the local experiment registry. This let the T4 do the expensive training while the repository remained the source of truth for honest cross-fitting, blending, comparison, and lineage.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;232&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The completed v2 run trained 28 neural networks in total: four ensemble members for each of seven folds. Under the deadline, the notebook was not just a convenient UI; it was the only realistic way to complete the full-scale neural experiment.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;236&quot; dir=&quot;auto&quot; id=&quot;the-blend-that-almost-passed&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;The blend that almost passed&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;238&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The FT model was introduced partly for diversity. I evaluated a predeclared grid of XGBoost/FT probability blends, correcting every blend with fold-external class decisions.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;242&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The best blend used &lt;strong&gt;75% XGBoost and 25% FT&lt;/strong&gt;. It reached &lt;strong&gt;0.950595&lt;/strong&gt;, improved six of seven folds, and had a paired bootstrap interval of +0.000035 to +0.000357 versus the incumbent.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;246&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;It still failed the promotion rule:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;248&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;248&quot; dir=&quot;auto&quot;&gt;the exact gain was &lt;strong&gt;+0.000197&lt;/strong&gt;, missing the +0.00020 threshold by about three millionths;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;250&quot; dir=&quot;auto&quot;&gt;unhealthy recall fell by &lt;strong&gt;0.001351&lt;/strong&gt;, well beyond the 0.00050 guardrail.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;252&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That is the kind of candidate the public leaderboard tempts you to submit. The framework rejected it. The final private result vindicated the value of having a standalone neural submission without claiming that every small OOF blend gain was real.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;257&quot; dir=&quot;auto&quot; id=&quot;what-did-not-work&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;What did not work&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;259&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The negative results were as useful as the winners because they narrowed the search under severe time and compute constraints.&lt;/p&gt;&lt;table class=&quot;code-line&quot; data-line=&quot;262&quot; dir=&quot;auto&quot; style=&quot;border-collapse: collapse; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em;&quot;&gt;&lt;thead class=&quot;code-line&quot; data-line=&quot;262&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;262&quot; dir=&quot;auto&quot;&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Experiment family&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Best relevant result&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Decision&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody class=&quot;code-line&quot; data-line=&quot;264&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;264&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Native CatBoost screen&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.948367&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Below matched XGBoost&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;265&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Hand-built health-range features&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;−0.000565 vs screen control&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Rejected&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;266&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Independent exact-stat XGBoost seed&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.950362&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Confirmed family, not a gain&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;267&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Missing-count features, full run&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.950293&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Screen gain did not transfer&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;268&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Structural XGBoost trial&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.950452&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Only +0.000054; recall guards failed&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;269&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;RealMLP-TD screen&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.948076&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Weaker and insufficiently diverse&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;270&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Class weighting, best corrected screen&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;+0.000082 vs control&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Below promotion threshold&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;271&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Richer temperature scaling&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;temperatures converged to 1.0&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;No value beyond offsets&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;272&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Two newly probed interactions, full run&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;0.950303&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Two fold wins; unhealthy recall failed&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;274&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The common pattern was important: many ideas improved raw argmax accuracy or a three-fold screen, then disappeared after class-aware correction or full seven-fold confirmation. Balanced accuracy was won at the interaction between probabilities and decisions, not by maximizing a convenient proxy.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;279&quot; dir=&quot;auto&quot; id=&quot;how-the-095306-public-score-was-produced&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;How the 0.95306 public score was produced&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;281&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The final public submission was a separate, late competition experiment. It began from the public &lt;strong&gt;V98 anchor&lt;/strong&gt;, which scored 0.95303, and applied an explicit ledger of 29 row-level label corrections recovered through controlled small-block ablations.&lt;/p&gt;&lt;table class=&quot;code-line&quot; data-line=&quot;285&quot; dir=&quot;auto&quot; style=&quot;border-collapse: collapse; color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em;&quot;&gt;&lt;thead class=&quot;code-line&quot; data-line=&quot;285&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;285&quot; dir=&quot;auto&quot;&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;Transition&lt;/span&gt;&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;Rows&lt;/span&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody class=&quot;code-line&quot; data-line=&quot;287&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;287&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;unhealthy&lt;/code&gt; → &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;at-risk&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;20&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;288&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;fit&lt;/code&gt; → &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;at-risk&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;5&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;289&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;at-risk&lt;/code&gt; → &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;unhealthy&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;4&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;290&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;Total&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;29&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;292&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The notebook checked the anchor&#39;s exact SHA-256, schema, row count, row order, label domain, and every expected source label before changing a row. It then round-trip validated the CSV and asserted the final output hash:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;296&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;4171D46147B36CEA16AF087FED7BE36BFD9B4BD48098B3D5D20A129123AFBB81&lt;span style=&quot;color: #d4d4d4;&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;300&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That tiny patch raised the public score from 0.95303 to &lt;strong&gt;0.95306&lt;/strong&gt;, producing public rank 63. Its private score was &lt;strong&gt;0.95018&lt;/strong&gt;, substantially below the FT model&#39;s 0.95084. The result is therefore best understood as a reproducible public-leader board clean-up, not evidence of a better classifier.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;305&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;I am including this detail because a useful competition retrospective should explain both what worked and what merely scored. The 29-row artifact explains the latest public score; the FT-Transformer explains the private finish.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;309&quot; dir=&quot;auto&quot; id=&quot;what-i-would-carry-into-the-next-competition&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;What I would carry into the next competition&lt;/h2&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;311&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;311&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Optimize the competition metric at the decision layer.&lt;/strong&gt; On an imbalanced multiclass task, probability argmax can leave a huge amount of balanced accuracy unused.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;314&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Cross-fit every learned post-processing step.&lt;/strong&gt; Offsets, thresholds, target statistics, calibration, and ensemble weights can all leak if fitted and scored on the same OOF labels.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;317&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Test scale-dependent features at the scale where they should work.&lt;/strong&gt; Exact-value statistics were a false negative on small samples and a real gain on the full data.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;319&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Use a different model family for real diversity.&lt;/strong&gt; A second tree seed barely helped; the FT-Transformer created different errors and delivered the best private score.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;322&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Keep raw probabilities, not just labels.&lt;/strong&gt; Stored OOF and test probabilities made later calibration, disagreement analysis, and blending possible without retraining.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;324&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Predeclare promotion gates.&lt;/strong&gt; A +0.000197 blend can look irresistible until its class-recall regression is measured.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;326&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Treat public leaderboard engineering as a separate layer.&lt;/strong&gt; It may be a valid competition tactic, but it should never be confused with private generalization.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;328&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Use hosted notebooks strategically.&lt;/strong&gt; Under a six-day deadline, Kaggle&#39;s T4 was essential for experiments that could not be completed safely on local hardware.&lt;/li&gt;&lt;/ol&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;331&quot; dir=&quot;auto&quot; id=&quot;final-reflection&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Final reflection&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;333&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Moving from a 0.92933 first submission and public rank around 1,880 to &lt;strong&gt;8th private and 63rd public&lt;/strong&gt; was not the result of one magic hyperparameter. It came from a sequence of compounding decisions:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;337&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;337&quot; dir=&quot;auto&quot;&gt;audit the data;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;338&quot; dir=&quot;auto&quot;&gt;align validation with balanced accuracy;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;339&quot; dir=&quot;auto&quot;&gt;fit target statistics inside folds;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;340&quot; dir=&quot;auto&quot;&gt;preserve OOF probabilities;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;341&quot; dir=&quot;auto&quot;&gt;add class-aware decisions;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;342&quot; dir=&quot;auto&quot;&gt;demand repeated evidence;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;343&quot; dir=&quot;auto&quot;&gt;use Kaggle Notebooks when local compute became the bottleneck;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;344&quot; dir=&quot;auto&quot;&gt;record negative results instead of repeating them;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;345&quot; dir=&quot;auto&quot;&gt;separate a generalized model gain from public leaderboard post-processing.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;347&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The most satisfying number is not 0.95306. It is &lt;strong&gt;8th on the private leaderboard&lt;/strong&gt;. That is the result produced by the modelling pipeline when the hidden 80% of the test labels finally decided the competition.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;351&quot; dir=&quot;auto&quot; id=&quot;reproducibility-and-links&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Reproducibility and links&lt;/h2&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;353&quot; dir=&quot;auto&quot; style=&quot;color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;353&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;https://www.kaggle.com/competitions/playground-series-s6e7&quot; href=&quot;https://www.kaggle.com/competitions/playground-series-s6e7&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Competition: Predicting Student Health Risk&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;354&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;https://github.com/JordiCorbilla/kaggle-medal-framework&quot; href=&quot;https://github.com/JordiCorbilla/kaggle-medal-framework&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Project repository&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;355&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;validation-strategy.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/kaggle-medal-framework/docs/validation-strategy.md&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Validation strategy&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;356&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;experiment-log.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/kaggle-medal-framework/docs/experiment-log.md&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Full experiment log&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;357&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;post-0950-results.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/kaggle-medal-framework/docs/post-0950-results.md&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Post-0.950 research results&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;358&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;dl-class-balance-results.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/kaggle-medal-framework/docs/dl-class-balance-results.md&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Deep-learning and class-balance results&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;359&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;training-feature-probing.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/kaggle-medal-framework/docs/training-feature-probing.md&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Training-only feature probing&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;360&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;https://www.kaggle.com/code/jordicorbilla/public-lb-0-95306-reproducible-29-row-cleanup&quot; href=&quot;https://www.kaggle.com/code/jordicorbilla/public-lb-0-95306-reproducible-29-row-cleanup&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Public 0.95306 cleanup notebook&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;361&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;https://www.kaggle.com/datasets/yw8837/ps-s6e7-095301-public-solution-pack&quot; href=&quot;https://www.kaggle.com/datasets/yw8837/ps-s6e7-095301-public-solution-pack&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Public 0.95301 solution pack credited by the cleanup notebook&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;362&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;https://www.kaggle.com/competitions/playground-series-s6e7/discussion/731469&quot; href=&quot;https://www.kaggle.com/competitions/playground-series-s6e7/discussion/731469&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;Clean-up experiment discussion&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;364&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;All local validation figures in this post come from aligned stored OOF predictions. Final public/private submission scores and leader board positions were reconciled against the authenticated Kaggle API after the competition closed on 31 July 2026.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/08/from-1880th-to-8th-six-day-validation.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp2i6eaBWGrWUhItZNTvVLVVa4podz2y415rimfKpibO25cByLQlmBwPgQOxXjVhmE-bqXTs2HYRKDNe3iVW_8cMGnRpWU7dXE3fU8PWQpQxRp0dSXAgOaNfu0mhhVMYFF8fQ2CWyyjA_uCghQm8ZDBXbmdKmZZp4vuGkDHdn51qtz-5qvQdFpemd-W7Y/s72-c/ChatGPT%20Image%20Aug%201,%202026,%2007_35_51%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-788824362116430395</guid><pubDate>Thu, 23 Jul 2026 21:31:06 +0000</pubDate><atom:updated>2026-07-23T21:31:06.306+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">gpt</category><category domain="http://www.blogger.com/atom/ns#">llm</category><category domain="http://www.blogger.com/atom/ns#">training</category><title>Building a GPT-Style Language Model From Scratch, One Understandable Step at a Time</title><description>&lt;h1 class=&quot;code-line code-active-line&quot; data-line=&quot;0&quot; dir=&quot;auto&quot; id=&quot;building-a-gpt-style-language-model-from-scratch-one-understandable-step-at-a-time&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 0px; padding-bottom: 0.3em;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhN6bJJiJLhm03Pe5qV3IOyMaL2TwEcQ2v3yM6H5u7QSw5MLIOv77DaFKpGd91f_GVEHodeVyf7XoAd2JUfJu2XLe6N8ZC-s5stDU02qIqbVNRT0vzFR8k9OUYXH0d1KRThB5Yr5h27VsvTN3EvWvyeqcDU4j5vlSTh2UifL6v3dSFG6Cg8f6Jigns8Mk/s1672/ChatGPT%20Image%20Jul%2023,%202026,%2010_29_25%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;941&quot; data-original-width=&quot;1672&quot; height=&quot;225&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhN6bJJiJLhm03Pe5qV3IOyMaL2TwEcQ2v3yM6H5u7QSw5MLIOv77DaFKpGd91f_GVEHodeVyf7XoAd2JUfJu2XLe6N8ZC-s5stDU02qIqbVNRT0vzFR8k9OUYXH0d1KRThB5Yr5h27VsvTN3EvWvyeqcDU4j5vlSTh2UifL6v3dSFG6Cg8f6Jigns8Mk/w400-h225/ChatGPT%20Image%20Jul%2023,%202026,%2010_29_25%20PM.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/h1&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;2&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Large language models can feel mysterious because we usually meet them only after they have been trained on enormous datasets using equally enormous computers. &lt;b&gt;FrankenGPT &lt;/b&gt;takes the opposite approach: make the model small enough to run locally, keep the implementation readable, and expose the complete path from a text file to generated text.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;7&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The result is not a replacement for ChatGPT, and that is not the goal. It is a compact, working GPT-style language model that lets us inspect the same essential ideas: tokenization, causal self-attention, next-token prediction, gradient-based optimization, validation, checkpoints, and autoregressive generation.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This article walks through that path without assuming that you already speak fluent Transformer.&lt;/p&gt;&lt;blockquote class=&quot;code-line&quot; data-line=&quot;15&quot; dir=&quot;auto&quot; style=&quot;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(34, 34, 34); border-color: rgba(0, 122, 204, 0.5); border-left-style: solid; border-left-width: 5px; border-radius: 2px; color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin: 0px; padding: 0px 16px 0px 10px;&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;15&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 16px; margin-top: 0px;&quot;&gt;Repository: &lt;a data-href=&quot;https://github.com/JordiCorbilla/llm-from-scratch&quot; href=&quot;https://github.com/JordiCorbilla/llm-from-scratch&quot; style=&quot;color: #3794ff; text-decoration: none;&quot;&gt;JordiCorbilla/llm-from-scratch&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot; id=&quot;what-does-from-scratch-mean-here&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;What does &quot;from scratch&quot; mean here?&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;19&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The phrase is important. In FrankenGPT&#39;s scratch workflow:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;21&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;21&quot; dir=&quot;auto&quot;&gt;no pretrained model weights are downloaded;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;22&quot; dir=&quot;auto&quot;&gt;no pretrained tokenizer is reused;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot;&gt;the vocabulary is built from the text we provide;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;24&quot; dir=&quot;auto&quot;&gt;every model parameter starts with a random value; and&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot;&gt;every saved checkpoint is the result of our own training run.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The repository also contains an optional Hugging Face fine-tuning example, but that is a separate experiment and is clearly labelled as pretrained. Everything in this article uses the scratch model.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;31&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;It is also worth being precise about the word &lt;em&gt;large&lt;/em&gt;. FrankenGPT follows the architecture and training objective used by GPT-like language models, but our experiments range from roughly 90,000 to 2.9 million parameters. That is deliberately small by modern LLM standards. Small models are much easier to understand, test, and train on an ordinary computer.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;37&quot; dir=&quot;auto&quot; id=&quot;the-whole-journey-in-one-view&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;The whole journey in one view&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;39&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The model&#39;s job can be summarized as a pipeline:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;41&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;corpus text
  -&amp;gt; tokenizer and vocabulary
  -&amp;gt; shifted input/target sequences
  -&amp;gt; token and position embeddings
  -&amp;gt; causal Transformer blocks
  -&amp;gt; next-token scores
  -&amp;gt; cross-entropy loss
  -&amp;gt; AdamW parameter updates
  -&amp;gt; checkpoint
  -&amp;gt; one-token-at-a-time generation
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Training repeatedly moves from left to right until the model becomes better at predicting the next token. Generation then reuses the trained model one prediction at a time.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;57&quot; dir=&quot;auto&quot; id=&quot;step-1-create-a-clean-environment&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 1: Create a clean environment&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;FrankenGPT requires Python 3.10 or newer. A virtual environment keeps this experiment separate from other Python projects:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;62&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;git clone https://github.com/JordiCorbilla/llm&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-from-scratch&lt;/span&gt;.git
&lt;span class=&quot;hljs-built_in&quot; style=&quot;color: #4ec9b0;&quot;&gt;cd&lt;/span&gt; llm&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-from-scratch&lt;/span&gt;

python &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-m&lt;/span&gt; venv .venv
.\.venv\Scripts\Activate.ps1
python &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-m&lt;/span&gt; pip install &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--upgrade&lt;/span&gt; pip
python &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-m&lt;/span&gt; pip install &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;.[dev]&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;72&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;On macOS or Linux, activate the environment with:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;74&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-built_in&quot; style=&quot;color: #4ec9b0;&quot;&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;78&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The editable installation gives us the &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;frankengpt&lt;/code&gt; command while keeping the source code available to inspect and change.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;81&quot; dir=&quot;auto&quot; id=&quot;confirming-gpu-support&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;&quot;&gt;Confirming GPU support&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;83&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;CPU training works everywhere and is useful for the first smoke test. An NVIDIA GPU makes the larger experiments much faster, but PyTorch must have been installed with CUDA support:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;87&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;python &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;import torch; print(torch.__version__, torch.cuda.is_available())&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;91&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;A CUDA-enabled installation prints a version containing &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;+cu...&lt;/code&gt; and then &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;True&lt;/code&gt;. If it prints &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;False&lt;/code&gt;, use the official &lt;a data-href=&quot;https://pytorch.org/get-started/locally/&quot; href=&quot;https://pytorch.org/get-started/locally/&quot; style=&quot;text-decoration: none;&quot;&gt;PyTorch installation selector&lt;/a&gt; to choose the wheel that matches the machine.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;FrankenGPT accepts &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--device auto&lt;/code&gt;, &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--device cpu&lt;/code&gt;, or &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--device cuda&lt;/code&gt;. On CUDA it automatically uses mixed-precision training: some operations use lower-precision numbers to improve GPU throughput and reduce memory use, while gradient scaling protects the optimization process from numerical underflow.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;101&quot; dir=&quot;auto&quot; id=&quot;step-2-choose-the-training-text&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 2: Choose the training text&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;103&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;A language model learns statistical patterns from its corpus. It does not receive a grammar book or a database of facts; it only sees sequences of tokens and tries to predict what follows.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;107&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For the first experiment, FrankenGPT can download Mary Shelley&#39;s &lt;em&gt;Frankenstein&lt;/em&gt; from Project Gutenberg:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;110&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;frankengpt train &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--download&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;data&lt;/span&gt;/pg84.txt ...
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;114&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The loader removes the Project Gutenberg catalogue header and licence footer before training. It then makes a contiguous split:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot;&gt;approximately 90% of the tokens are used for training;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;118&quot; dir=&quot;auto&quot;&gt;approximately 10% are held out for validation.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;120&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Those partitions do not overlap. The training portion updates the weights; the validation portion measures whether the learned patterns also work on unseen text.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;123&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For a broader experiment, the project can download several public-domain classics:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;125&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;frankengpt fetch&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-data&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--output-dir&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;data&lt;/span&gt;/classics
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;More varied data matters. A model trained on one novel mostly learns the vocabulary, punctuation, characters, and style of that novel. A multi-book corpus exposes it to more sentence structures and word combinations.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; id=&quot;step-3-turn-text-into-tokens&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 3: Turn text into tokens&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Neural networks operate on numbers, not strings. A tokenizer divides text into units and assigns an integer ID to each unit.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;138&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;FrankenGPT includes two intentionally simple tokenizers:&lt;/p&gt;&lt;table class=&quot;code-line&quot; data-line=&quot;140&quot; dir=&quot;auto&quot; style=&quot;border-collapse: collapse; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em;&quot;&gt;&lt;thead class=&quot;code-line&quot; data-line=&quot;140&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;140&quot; dir=&quot;auto&quot;&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Tokenizer&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Example units&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Trade-off&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody class=&quot;code-line&quot; data-line=&quot;142&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;142&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Character&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;[&quot;T&quot;, &quot;h&quot;, &quot;e&quot;]&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Small vocabulary and no unknown words, but long sequences&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Word&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;[&quot;The&quot;, &quot;creature&quot;, &quot;,&quot;]&lt;/code&gt;&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;More readable output and shorter sequences, but a larger vocabulary&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;145&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Both vocabularies are built only from the selected corpus. For example:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;147&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;text:       The creature
tokens:     [&quot;The&quot;, &quot;creature&quot;]
token IDs:  [418, 937]
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;153&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The IDs themselves have no linguistic meaning. They are indexes into a learned embedding table. During training, the vector at each index gradually becomes useful for predicting tokens that tend to appear nearby.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;157&quot; dir=&quot;auto&quot; id=&quot;step-4-create-the-question-and-the-answer&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 4: Create the question and the answer&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;159&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The training objective is next-token prediction. Given a sequence of token IDs, the target is the same sequence shifted by one position:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;token stream:  [12, 31, 7, 44, 9]
input:         [12, 31, 7, 44]
target:        [31, 7, 44, 9]
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;168&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This produces several predictions in one forward pass:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;170&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;170&quot; dir=&quot;auto&quot;&gt;after &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;12&lt;/code&gt;, predict &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;31&lt;/code&gt;;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;171&quot; dir=&quot;auto&quot;&gt;after &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;12, 31&lt;/code&gt;, predict &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;7&lt;/code&gt;;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;172&quot; dir=&quot;auto&quot;&gt;after &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;12, 31, 7&lt;/code&gt;, predict &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;44&lt;/code&gt;; and&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;173&quot; dir=&quot;auto&quot;&gt;after &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;12, 31, 7, 44&lt;/code&gt;, predict &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;9&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;175&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;With batch size &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;B&lt;/code&gt; and context length &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;T&lt;/code&gt;, the input and target tensors both have shape &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;[B, T]&lt;/code&gt;.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;178&quot; dir=&quot;auto&quot; id=&quot;step-5-pass-the-tokens-through-a-gpt-style-decoder&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 5: Pass the tokens through a GPT-style decoder&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;180&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The model first combines two learned representations:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;182&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;182&quot; dir=&quot;auto&quot;&gt;a &lt;strong&gt;token embedding&lt;/strong&gt;, which represents the current token;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;183&quot; dir=&quot;auto&quot;&gt;a &lt;strong&gt;position embedding&lt;/strong&gt;, which represents where that token appears in the sequence.&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;185&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The combined vectors pass through a stack of Transformer decoder blocks. Each block contains pre-layer normalization, multi-head causal self-attention, a GELU feed-forward network, dropout, and residual&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;connections.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;189&quot; dir=&quot;auto&quot; id=&quot;causal-self-attention-gently-explained&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px;&quot;&gt;Causal self-attention, gently explained&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;191&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Self-attention lets each position decide which earlier positions are useful. Internally, the model projects each token representation into queries, keys, and values:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;194&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;queries, keys, values  [B, heads, T, head dimension]
attention scores       [B, heads, T, T]
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;199&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The core operation is:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;201&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;attention(Q, K, V) = softmax((Q K^T / sqrt(d_k)) + causal_mask) V
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;205&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The notation is more compact than the idea. &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;Q K^T&lt;/code&gt; measures which tokens are relevant to one another, the scale factor keeps the numbers stable, the mask removes future tokens, softmax turns the remaining scores into proportions, and those proportions select a mixture of the value vectors.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;210&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The causal mask blocks every future position. When predicting token 5, the model may use tokens 0 through 4, but it cannot peek at token 5&#39;s answer. Without this restriction, training loss would look excellent while generation would fail: the model would have learned to copy information that is unavailable when writing new text.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;215&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Residual connections preserve a direct path through the network, while the feed-forward layers transform each position independently. Repeating the block lets the model build progressively richer contextual representations.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;219&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Finally, a linear language-model head produces one score, or &lt;em&gt;logit&lt;/em&gt;, for every item in the vocabulary:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;222&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;hidden states  [B, T, model width]
logits         [B, T, vocabulary size]
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;227&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;FrankenGPT ties the output head to the token embedding table. The same learned token representations therefore support both reading input and scoring output, while reducing the parameter count.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;231&quot; dir=&quot;auto&quot; id=&quot;step-6-measure-the-error-and-update-the-model&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 6: Measure the error and update the model&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;233&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Cross-entropy loss compares the logits with the correct shifted targets. Lower loss means that the model assigned more probability to the actual next tokens.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;236&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;One training update performs:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;238&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;forward pass
  -&amp;gt; cross-entropy loss
  -&amp;gt; backpropagation
  -&amp;gt; gradient clipping
  -&amp;gt; AdamW update
  -&amp;gt; learning-rate schedule
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;247&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The optimizer is AdamW. The learning rate warms up gradually and then follows a cosine decay. Gradient clipping limits unusually large updates, and weight decay discourages parameters from growing without bound.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;251&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;There are two losses to watch:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;253&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;253&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;training loss&lt;/strong&gt; is measured on text used to update the model;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;254&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;validation loss&lt;/strong&gt; is measured on held-out text that never updates the model.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;256&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;We want both to decrease. If training loss continues downward while validation loss begins to rise, the model is memorizing the training corpus more than it is learning patterns that transfer. That is overfitting.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;260&quot; dir=&quot;auto&quot; id=&quot;step-7-prove-the-complete-pipeline-with-a-smoke-run&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 7: Prove the complete pipeline with a smoke run&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;262&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Before spending time on a long training run, it is sensible to test every stage with a small CPU model:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;265&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;frankengpt train &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--download&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;data&lt;/span&gt;/pg84.txt &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--tokenizer&lt;/span&gt; word &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--max-vocab&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;2048&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--device&lt;/span&gt; cpu &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--output&lt;/span&gt; runs/readme&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-smoke&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--max-steps&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--batch-size&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;8&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--context-length&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--d-model&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--n-heads&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--n-layers&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--eval-interval&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;271&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This model has 91,520 parameters. In a verified run, training loss moved from &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;7.6218&lt;/code&gt; to &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;7.5856&lt;/code&gt;, while validation loss moved from &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;7.6328&lt;/code&gt; to &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;7.6039&lt;/code&gt;.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;274&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That is a small improvement, as expected after only ten updates. At this stage, success means that:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;277&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;277&quot; dir=&quot;auto&quot;&gt;data was loaded and tokenized;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;278&quot; dir=&quot;auto&quot;&gt;forward and backward passes completed;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;279&quot; dir=&quot;auto&quot;&gt;both losses were recorded;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;280&quot; dir=&quot;auto&quot;&gt;checkpoints were saved; and&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;281&quot; dir=&quot;auto&quot;&gt;the checkpoint could be loaded for generation.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;283&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The generated text is not supposed to be fluent yet:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;285&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;The earth interested does desires enemy affectionate desires disappeared figure figure
figure desires distinct noble.. the familiar valley valley safety disappeared disappeared
the
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;291&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This output is useful precisely because it sets an honest baseline. Ten steps validate the machinery; they do not teach a language model to write.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;294&quot; dir=&quot;auto&quot; id=&quot;step-8-train-the-larger-model-on-a-gpu&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 8: Train the larger model on a GPU&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;296&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The more interesting run used the word tokenizer and a collection of public-domain classics:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;299&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;frankengpt fetch&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-data&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--output-dir&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;data&lt;/span&gt;/classics

frankengpt train &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;data&lt;/span&gt;/classics/*.txt &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--tokenizer&lt;/span&gt; word &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--max-vocab&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;16384&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--device&lt;/span&gt; cuda &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--output&lt;/span&gt; runs/classics&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-word-v2&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--max-steps&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;2000&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--batch-size&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--context-length&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;64&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--d-model&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;128&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--n-heads&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;4&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--n-layers&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--eval-interval&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;308&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Its configuration was:&lt;/p&gt;&lt;table class=&quot;code-line&quot; data-line=&quot;310&quot; dir=&quot;auto&quot; style=&quot;border-collapse: collapse; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em;&quot;&gt;&lt;thead class=&quot;code-line&quot; data-line=&quot;310&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;310&quot; dir=&quot;auto&quot;&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: left;&quot;&gt;Setting&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Value&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody class=&quot;code-line&quot; data-line=&quot;312&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;312&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Parameters&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;2,898,688&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;313&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Vocabulary&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;16,384 word and punctuation tokens&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;314&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Context length&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;64 tokens&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;315&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Transformer blocks&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;316&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Attention heads&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;317&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Model width&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;128&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;318&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Batch size&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;32&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;319&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Training steps&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;2,000&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;320&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px;&quot;&gt;Device&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;CUDA&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;322&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;On the test machine, an NVIDIA GeForce RTX 2060 ran the model through CUDA mixed precision. The recorded training segment processed approximately 44,868 tokens per second. Throughput is hardware- and software-dependent, so the loss trend is the more portable result.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;327&quot; dir=&quot;auto&quot; id=&quot;step-9-save-checkpoints-and-keep-the-best-model&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 9: Save checkpoints and keep the best model&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;329&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;At each evaluation interval, FrankenGPT writes:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;331&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;331&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;checkpoint_last.pt&lt;/code&gt;, containing the newest state;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;332&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;checkpoint_best.pt&lt;/code&gt;, containing the lowest validation loss seen so far; and&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;333&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;metrics.json&lt;/code&gt;, containing throughput and loss history.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;335&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The checkpoint includes the model configuration, tokenizer vocabulary, model parameters, optimizer, learning-rate scheduler, training step, and history. That makes it possible to resume training rather than restart:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;339&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;frankengpt train &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;data&lt;/span&gt;/classics/*.txt &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--tokenizer&lt;/span&gt; word &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--max-vocab&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;16384&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--device&lt;/span&gt; cuda &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--output&lt;/span&gt; runs/classics&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-word-v2&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--resume&lt;/span&gt; runs/classics&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-word-v2&lt;/span&gt;/checkpoint_last.pt `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--max-steps&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;3000&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--batch-size&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--context-length&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;64&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--d-model&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;128&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--n-heads&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--n-layers&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--eval-interval&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;347&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Model shape and tokenizer settings must remain unchanged when resuming. Only the training budget and other compatible operational settings should change.&lt;/p&gt;&lt;blockquote class=&quot;code-line&quot; data-line=&quot;350&quot; dir=&quot;auto&quot; style=&quot;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(34, 34, 34); border-color: rgba(0, 122, 204, 0.5); border-left-style: solid; border-left-width: 5px; border-radius: 2px; color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin: 0px; padding: 0px 16px 0px 10px;&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;350&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 16px; margin-top: 0px;&quot;&gt;Load PyTorch &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; color: #d7ba7d; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.pt&lt;/code&gt; checkpoints only from trusted sources because they can contain pickled Python data.&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;353&quot; dir=&quot;auto&quot; id=&quot;what-did-the-model-learn&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;What did the model learn?&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;355&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The multi-book model&#39;s measured losses were:&lt;/p&gt;&lt;table class=&quot;code-line&quot; data-line=&quot;357&quot; dir=&quot;auto&quot; style=&quot;border-collapse: collapse; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em;&quot;&gt;&lt;thead class=&quot;code-line&quot; data-line=&quot;357&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;357&quot; dir=&quot;auto&quot;&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Step&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Training loss&lt;/th&gt;&lt;th style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.69); border-left-color: rgba(255, 255, 255, 0.69); border-right-color: rgba(255, 255, 255, 0.69); border-top-color: rgba(255, 255, 255, 0.69); padding: 5px 10px; text-align: right;&quot;&gt;Validation loss&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody class=&quot;code-line&quot; data-line=&quot;359&quot; dir=&quot;auto&quot;&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;359&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;100&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;6.6836&lt;/td&gt;&lt;td style=&quot;border-color: rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;6.7742&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;360&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;1,000&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;5.1567&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;5.4137&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;code-line&quot; data-line=&quot;361&quot; dir=&quot;auto&quot;&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;2,000&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;5.0342&lt;/td&gt;&lt;td style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top: 1px solid rgba(255, 255, 255, 0.18); padding: 5px 10px; text-align: right;&quot;&gt;5.3361&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;363&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Both values fell substantially, and validation loss was still improving at step 2,000. That is evidence that the model learned patterns that also applied to the held-out text.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;366&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Loss values from the word model should not be compared directly with the character model&#39;s losses. Their vocabularies and prediction problems are different: choosing among 16,384 words is not the same task as choosing among 93 characters. Loss trends within one run are what matter.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;371&quot; dir=&quot;auto&quot; id=&quot;the-eventual-output&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;The eventual output&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;373&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Generation begins with a prompt and repeatedly samples one next token:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;375&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;frankengpt generate &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--checkpoint&lt;/span&gt; runs/classics&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-word-v2&lt;/span&gt;/checkpoint_best.pt `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--prompt&lt;/span&gt; &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;I had worked hard&quot;&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--max-new-tokens&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;80&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--temperature&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.7&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--top-k&lt;/span&gt; &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--device&lt;/span&gt; cuda
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;381&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;A fresh sample from the trained checkpoint produced:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;383&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;I had worked hard, and all the house of a moment of my own friend, and that I am, with a
great. But I shall not not be no time, you shall have been no, it is all the door, my own,
to be so. What may not know. I see that I can do you will be a man, I cannot know you have
been as I can be so that my
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;390&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The difference from the ten-step smoke output is visible. The larger model learned:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;392&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;392&quot; dir=&quot;auto&quot;&gt;plausible English punctuation;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;393&quot; dir=&quot;auto&quot;&gt;common phrase and clause structures;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;394&quot; dir=&quot;auto&quot;&gt;agreement between many neighbouring words; and&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;395&quot; dir=&quot;auto&quot;&gt;a rough literary rhythm from the source corpus.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;397&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;It also repeats itself, contradicts itself, and loses the thread. That is the expected boundary of this experiment, not a hidden failure. A 2.9-million-parameter model trained for 2,000 updates on a handful of books has learned local language patterns, not robust reasoning, factual knowledge, or long-range narrative planning.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;402&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Sampling settings change the style but cannot create knowledge the model did not learn. A lower temperature and smaller &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;top-k&lt;/code&gt; make output safer and more repetitive. Higher values add variety along with more mistakes.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;406&quot; dir=&quot;auto&quot; id=&quot;step-10-verify-and-benchmark-the-result&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 10: Verify and benchmark the result&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;408&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The repository includes automated checks for tokenization, shifted targets, causal masking, model shapes, loss handling, checkpoint loading, resumption, compilation fallbacks, and generation:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;412&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;python &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-m&lt;/span&gt; ruff check .
python &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-m&lt;/span&gt; pytest
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;417&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Benchmark a saved model separately:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-radius: 3px; border: 1px solid rgb(48, 48, 49); color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;419&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;frankengpt benchmark &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--checkpoint&lt;/span&gt; runs/classics&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-word-v2&lt;/span&gt;/checkpoint_best.pt &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;--device&lt;/span&gt; cuda
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;423&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Forward-pass throughput and autoregressive generation throughput are different measurements. A forward pass predicts many positions in parallel; generation must append one token and run the model again before it can choose the next.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;427&quot; dir=&quot;auto&quot; id=&quot;what-would-improve-it-next&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;What would improve it next?&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;429&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The project is intentionally a foundation rather than an endpoint. The highest-impact next experiments are:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;432&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;432&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Use more varied text.&lt;/strong&gt; Data diversity improves vocabulary and generalization.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;433&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Add a subword tokenizer.&lt;/strong&gt; Subwords balance the long sequences of characters against the very large vocabulary and unknown words of a simple word tokenizer.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;435&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Increase context length.&lt;/strong&gt; The model can then condition on more history, at a higher memory and compute cost.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;437&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Scale width and depth carefully.&lt;/strong&gt; More parameters increase capacity only when the dataset and training budget grow with them.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;439&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Track validation first.&lt;/strong&gt; More training is useful until held-out performance stops improving.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;441&quot; dir=&quot;auto&quot;&gt;&lt;strong&gt;Evaluate multiple prompts and seeds.&lt;/strong&gt; One attractive sample is not a complete model evaluation.&lt;/li&gt;&lt;/ol&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;444&quot; dir=&quot;auto&quot; id=&quot;closing-thought&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Closing thought&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;446&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The most valuable output of FrankenGPT is not a perfect paragraph. It is the removal of the black box.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;449&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;We can point to the corpus, vocabulary, shifted targets, embeddings, masked attention, loss, gradients, optimizer, checkpoint, and sampling loop. We can see the validation loss fall, resume the exact training state, move the computation to a GPU, and inspect what the model learned—and what it did not.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;454&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That is the real benefit of building a language model from scratch: every generated token has a path we can follow.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/07/building-gpt-style-language-model-from.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhN6bJJiJLhm03Pe5qV3IOyMaL2TwEcQ2v3yM6H5u7QSw5MLIOv77DaFKpGd91f_GVEHodeVyf7XoAd2JUfJu2XLe6N8ZC-s5stDU02qIqbVNRT0vzFR8k9OUYXH0d1KRThB5Yr5h27VsvTN3EvWvyeqcDU4j5vlSTh2UifL6v3dSFG6Cg8f6Jigns8Mk/s72-w400-h225-c/ChatGPT%20Image%20Jul%2023,%202026,%2010_29_25%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-6791802610852486777</guid><pubDate>Sat, 27 Jun 2026 17:43:19 +0000</pubDate><atom:updated>2026-06-27T17:43:19.339+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">algorithmic</category><category domain="http://www.blogger.com/atom/ns#">backtesting</category><category domain="http://www.blogger.com/atom/ns#">library</category><category domain="http://www.blogger.com/atom/ns#">portfolio</category><category domain="http://www.blogger.com/atom/ns#">Python</category><category domain="http://www.blogger.com/atom/ns#">quant</category><category domain="http://www.blogger.com/atom/ns#">riskoptima</category><category domain="http://www.blogger.com/atom/ns#">suite</category><category domain="http://www.blogger.com/atom/ns#">trading</category><title>RiskOptima in 2026: Turning a Quant Toolkit into a Five-Project Portfolio Platform</title><description>&lt;p&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgeVrgljGc9NWBXh8QttRj2sJ7ER_yLf9YTl83Wfq_V3GcndH83DR4ewPugVdxJxuR6zsZpASWRDUyG0EMc8AeqbEbKAk6VmMy0YrTzBxOPDdIBqmhPaHFzwhSUjn25f1EtufDoA2A7y4scpfjETks5LoeoZvuZeOgqTNjqyJpNypEY3YzOSK8-1Dprb6Y&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgeVrgljGc9NWBXh8QttRj2sJ7ER_yLf9YTl83Wfq_V3GcndH83DR4ewPugVdxJxuR6zsZpASWRDUyG0EMc8AeqbEbKAk6VmMy0YrTzBxOPDdIBqmhPaHFzwhSUjn25f1EtufDoA2A7y4scpfjETks5LoeoZvuZeOgqTNjqyJpNypEY3YzOSK8-1Dprb6Y&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;In April 2025, I wrote about the &lt;a href=&quot;https://thundaxsoftware.blogspot.com/2025/04/riskoptima-options-analysis-suite.html&quot;&gt;RiskOptima Options Analysis Suite: a practical options toolkit for implied volatility screening, Greeks simulation, and straddle backtesting&lt;/a&gt;.&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That version had a clear purpose: give traders and quant developers a compact way to look at options behaviour, volatility, and earnings-event risk using Python. It was deliberately hands-on: fetch market data, generate charts, inspect Greeks, and test a simple volatility trade.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;One year later, RiskOptima has grown into something broader.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;It is no longer just an options analysis script. It is becoming a structured quantitative finance toolkit that can demonstrate five canonical quant portfolio projects in one repository:&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgjv32p8ptbLIs5yPTLM9ft6D5RDH7twi3sssleLJkmAblUlNjOHO3bnVYF48bh-olO9cd8XMCTDtLPgimQXYIvOBGHo_FDfO3MMaKRHbfm3BDwmd3FGBdOTuLBFg4xfuVvB4dcV5GGA35WNuQbmRY3UMaIkKFiX5PNTZYd0MbJSV-jBjkccM8p4XyUIrw&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;600&quot; data-original-width=&quot;1350&quot; height=&quot;284&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgjv32p8ptbLIs5yPTLM9ft6D5RDH7twi3sssleLJkmAblUlNjOHO3bnVYF48bh-olO9cd8XMCTDtLPgimQXYIvOBGHo_FDfO3MMaKRHbfm3BDwmd3FGBdOTuLBFg4xfuVvB4dcV5GGA35WNuQbmRY3UMaIkKFiX5PNTZYd0MbJSV-jBjkccM8p4XyUIrw=w640-h284&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Caption: RiskOptima now includes dashboard-ready analytics, pricing engines, backtesting utilities, optimization workflows, and credit risk modelling.&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot;&gt;Algorithmic trading and backtesting&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;15&quot; dir=&quot;auto&quot;&gt;Portfolio optimization&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot;&gt;Market risk dashboarding&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot;&gt;Option pricing and Greeks&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot;&gt;Credit risk modelling&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That matters because a quant portfolio should not just show isolated notebooks. It should show that you can build reusable models, package them cleanly, test them, and explain how they fit into real investment and risk workflows.&lt;/p&gt;&lt;h2 style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; margin-bottom: 16px; margin-top: 0px; text-align: left;&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;From Options Suite to Quant Risk Platform&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The original options post focused on three practical workflows:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot;&gt;Implied volatility screening&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;29&quot; dir=&quot;auto&quot;&gt;Greeks simulation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot;&gt;Earnings straddle backtesting&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Those pieces are still valuable, but they now sit inside a wider architecture.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;RiskOptima now includes modules for:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot;&gt;Portfolio analytics&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;37&quot; dir=&quot;auto&quot;&gt;Mean-variance optimization&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot;&gt;Factor risk modelling&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;39&quot; dir=&quot;auto&quot;&gt;Backtesting with transaction costs&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot;&gt;VaR and CVaR&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;41&quot; dir=&quot;auto&quot;&gt;Monte Carlo simulation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot;&gt;Fixed-income analytics&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;43&quot; dir=&quot;auto&quot;&gt;Options pricing&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot;&gt;Credit risk modelling&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;45&quot; dir=&quot;auto&quot;&gt;Dashboard-ready market risk reporting&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;47&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The main shift is architectural. Instead of treating each notebook as a standalone experiment, RiskOptima now exposes cleaner package APIs that can be imported, tested, reused, and extended.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;49&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That is the difference between a tutorial project and a library.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;51&quot; dir=&quot;auto&quot; id=&quot;project-1-algorithmic-trading-backtester&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Project 1: Algorithmic Trading Backtester&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;53&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The backtesting layer provides strategy interfaces, portfolio state tracking, transaction cost modelling, and daily rebalancing workflows.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhtYAkHwShUrOq_IY8_QEErpbqZUL3VnbpvX-XM7CbwFYbPVe9-9g2dyCw5GYaU1V1MkVQzCwk4zKjVY0Jh_yT7pUD6ZKsivGpSecEZoMBwgNuksMUrAvLF1s06hPf0F1pRLzPkq31CxV9abhbBOt94EIaKxHudPCovY3gWBh5LzHplIr7-5RRta87t7m4&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;675&quot; data-original-width=&quot;1200&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhtYAkHwShUrOq_IY8_QEErpbqZUL3VnbpvX-XM7CbwFYbPVe9-9g2dyCw5GYaU1V1MkVQzCwk4zKjVY0Jh_yT7pUD6ZKsivGpSecEZoMBwgNuksMUrAvLF1s06hPf0F1pRLzPkq31CxV9abhbBOt94EIaKxHudPCovY3gWBh5LzHplIr7-5RRta87t7m4=w640-h360&quot; width=&quot;640&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Caption: A clean backtesting layer should produce an inspectable equity curve, weights through time, and trade/risk diagnostics.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The goal is not to compete with institutional backtesting engines. The goal is to show the mechanics clearly:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;61&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;61&quot; dir=&quot;auto&quot;&gt;Generate target weights&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;62&quot; dir=&quot;auto&quot;&gt;Rebalance a portfolio&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;63&quot; dir=&quot;auto&quot;&gt;Apply spread and impact costs&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;64&quot; dir=&quot;auto&quot;&gt;Track equity curves&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot;&gt;Inspect weights through time&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For example, a simple SMA crossover strategy can be expressed as a reusable strategy object and passed into the backtest engine.&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-python&quot; data-line=&quot;69&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;from&lt;/span&gt; riskoptima &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; BacktestConfig, SMACrossStrategy, SimpleCostModel, run_backtest

strategy = SMACrossStrategy(short_window=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;20&lt;/span&gt;, long_window=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;50&lt;/span&gt;)
config = BacktestConfig(initial_cash=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;1_000_000&lt;/span&gt;, rebalance_rule=&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;D&quot;&lt;/span&gt;)
cost_model = SimpleCostModel(spread_bps=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;2.0&lt;/span&gt;, impact_coeff=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.0&lt;/span&gt;)

equity_curve, weights = run_backtest(
    prices=prices,
    strategy=strategy,
    config=config,
    cost_model=cost_model,
)
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;84&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The important portfolio signal here is not that an SMA strategy is sophisticated. It is that the repo demonstrates the plumbing required to evaluate systematic strategies properly.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;86&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The SMA code has also been moved into the library itself instead of living only inside the notebook. That makes the notebook easier to read and gives users reusable functions for building signals, generating trade logs, and plotting entries and exits.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;88&quot; dir=&quot;auto&quot; id=&quot;project-2-portfolio-optimization&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Project 2: Portfolio Optimization&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;90&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;RiskOptima already had strong portfolio optimization foundations: efficient frontiers, Monte Carlo portfolio generation, Sharpe maximization, minimum variance portfolios, and allocation visualizations.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot; style=&quot;color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj3dQM43GOWXur7AZxuSf1RK6ARrZ-id_LUzy48_UVs7zZqQXPLaqlE46MRalB-QNCnzTWSER8E_e3CozDApQljU-IIO-xezBDFPo2xy7pgyFzBOnV0bTwfzFHJ-6cVM903RnJ0AlSXR79E6H-VabPE8aPy64kyeQOsPiBXynXDVOcc6HjIqNkkPz_Ojho&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;675&quot; data-original-width=&quot;1200&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj3dQM43GOWXur7AZxuSf1RK6ARrZ-id_LUzy48_UVs7zZqQXPLaqlE46MRalB-QNCnzTWSER8E_e3CozDApQljU-IIO-xezBDFPo2xy7pgyFzBOnV0bTwfzFHJ-6cVM903RnJ0AlSXR79E6H-VabPE8aPy64kyeQOsPiBXynXDVOcc6HjIqNkkPz_Ojho=w640-h360&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Caption: Portfolio optimization is where expected return, volatility, constraints, and risk-adjusted objectives come together.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The newer modular optimizer layer makes that cleaner:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-python&quot; data-line=&quot;98&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;from&lt;/span&gt; riskoptima &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; Constraints, optimize_max_sharpe

constraints = Constraints(
    weight_bounds=(&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.0&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.30&lt;/span&gt;),
    factor_bounds={&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;MKT&quot;&lt;/span&gt;: (-&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.2&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.8&lt;/span&gt;)},
)

weights = optimize_max_sharpe(
    expected_returns=expected_returns,
    cov=covariance_matrix,
    constraints=constraints,
    factor_exposures=factor_exposures,
    risk_free_rate=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.02&lt;/span&gt;,
)
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This gives the project a more realistic optimization story:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot;&gt;Long-only or bounded portfolios&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;118&quot; dir=&quot;auto&quot;&gt;Factor exposure controls&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot;&gt;Risk-adjusted objective functions&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;120&quot; dir=&quot;auto&quot;&gt;Reusable optimizer APIs&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;122&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For a quant portfolio, this is one of the most important sections. It shows that you understand portfolio construction, not just individual signal generation.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;124&quot; dir=&quot;auto&quot; id=&quot;project-3-market-risk-dashboard&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Project 3: Market Risk Dashboard&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;126&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;One of the biggest additions is the dashboard-ready market risk report layer.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;128&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; color: #d4d4d4; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEglVFi-bVuBfZoHY4t_-nFsjQRIGaNXrkzRcYIoY23nBCfYsMKTXQBMQadcdjQmMIcLXwb4FvRWbg0l0Y4V8uC_I8__YCcjDEK8lxD23ygeDodafmLPvVCevudzbhlkPJW_BKJ1xmJp_LxJ2eAaYQt2qsuETAqeUgkpDOkGMtrwX5TqO3RXMjmN7yFKVJY&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;600&quot; data-original-width=&quot;1350&quot; height=&quot;284&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEglVFi-bVuBfZoHY4t_-nFsjQRIGaNXrkzRcYIoY23nBCfYsMKTXQBMQadcdjQmMIcLXwb4FvRWbg0l0Y4V8uC_I8__YCcjDEK8lxD23ygeDodafmLPvVCevudzbhlkPJW_BKJ1xmJp_LxJ2eAaYQt2qsuETAqeUgkpDOkGMtrwX5TqO3RXMjmN7yFKVJY=w640-h284&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Caption: The market risk layer turns raw returns into dashboard metrics such as VaR, CVaR, drawdown, rolling volatility, and benchmark-relative risk.&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;132&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The new reporting module produces a structured risk report with:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;134&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;134&quot; dir=&quot;auto&quot;&gt;Annualized return&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot;&gt;Annualized volatility&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;136&quot; dir=&quot;auto&quot;&gt;Sharpe ratio&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;137&quot; dir=&quot;auto&quot;&gt;Sortino ratio&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;138&quot; dir=&quot;auto&quot;&gt;Maximum drawdown&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;139&quot; dir=&quot;auto&quot;&gt;Historical VaR&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;140&quot; dir=&quot;auto&quot;&gt;Parametric Gaussian VaR&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;141&quot; dir=&quot;auto&quot;&gt;CVaR / expected shortfall&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;142&quot; dir=&quot;auto&quot;&gt;Beta versus benchmark&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot;&gt;Tracking error&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;144&quot; dir=&quot;auto&quot;&gt;Information ratio&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;145&quot; dir=&quot;auto&quot;&gt;Rolling volatility&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;146&quot; dir=&quot;auto&quot;&gt;Rolling drawdown&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;148&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Example:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-python&quot; data-line=&quot;150&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;from&lt;/span&gt; riskoptima.reporting &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; build_market_risk_report

report = build_market_risk_report(
    returns=asset_returns,
    weights=portfolio_weights,
    benchmark_returns=benchmark_returns,
    confidence_levels=(&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.95&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.99&lt;/span&gt;),
)

&lt;span class=&quot;hljs-built_in&quot; style=&quot;color: #4ec9b0;&quot;&gt;print&lt;/span&gt;(report.metrics[&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;annualized_volatility&quot;&lt;/span&gt;])
&lt;span class=&quot;hljs-built_in&quot; style=&quot;color: #4ec9b0;&quot;&gt;print&lt;/span&gt;(report.metrics[&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;historical_var&quot;&lt;/span&gt;][&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.99&lt;/span&gt;])
&lt;span class=&quot;hljs-built_in&quot; style=&quot;color: #4ec9b0;&quot;&gt;print&lt;/span&gt;(report.metrics[&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;cvar&quot;&lt;/span&gt;][&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.99&lt;/span&gt;])
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;165&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;There are also plotting helpers for:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;167&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;167&quot; dir=&quot;auto&quot;&gt;Drawdown curves&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;168&quot; dir=&quot;auto&quot;&gt;Rolling volatility&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;169&quot; dir=&quot;auto&quot;&gt;VaR / CVaR loss distributions&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;170&quot; dir=&quot;auto&quot;&gt;Correlation heatmaps&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;172&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This turns RiskOptima into something that can support an actual risk dashboard rather than just isolated calculations.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;174&quot; dir=&quot;auto&quot; id=&quot;project-4-option-pricing-engine&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Project 4: Option Pricing Engine&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;176&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The original options suite has now been refactored into a cleaner option pricing engine.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;178&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEh6JJfFYU9jQYn-u80Gi6dnWtl9WHS9dAFISAcqw5JoPqypgKMRcCPEwp5hmgtm_ZSSal8IiWhfgpUpsmPguwDMZ1XzQNUFjzSCUXaiq7tmDO6UgR5H4TvULiK1O_GhSW-wK-Xj9OVTpXA9gwJE73Yyc8hXqQX0JwLaL3ngbSUAH1vRq_mLh2PtZ3N2ZRs&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;675&quot; data-original-width=&quot;1200&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEh6JJfFYU9jQYn-u80Gi6dnWtl9WHS9dAFISAcqw5JoPqypgKMRcCPEwp5hmgtm_ZSSal8IiWhfgpUpsmPguwDMZ1XzQNUFjzSCUXaiq7tmDO6UgR5H4TvULiK1O_GhSW-wK-Xj9OVTpXA9gwJE73Yyc8hXqQX0JwLaL3ngbSUAH1vRq_mLh2PtZ3N2ZRs=w640-h360&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Caption: The options engine separates pricing logic from notebook exploration, making Black-Scholes, Greeks, implied volatility, binomial trees, and Monte Carlo pricing reusable.&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;182&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The new &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;riskoptima.options&lt;/code&gt; package exposes:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;184&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;184&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;black_scholes_price&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;185&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;black_scholes_greeks&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;186&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;implied_volatility&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;187&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;binomial_tree_price&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;188&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;monte_carlo_european_option&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;190&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Example:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-python&quot; data-line=&quot;192&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;from&lt;/span&gt; riskoptima.options &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; (
    black_scholes_price,
    black_scholes_greeks,
    implied_volatility,
    monte_carlo_european_option,
)

S, K, T, r, sigma = &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;100&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;100&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;1.0&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.05&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.20&lt;/span&gt;

call = black_scholes_price(S, K, T, r, sigma, option_type=&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;call&quot;&lt;/span&gt;)
put = black_scholes_price(S, K, T, r, sigma, option_type=&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;put&quot;&lt;/span&gt;)
greeks = black_scholes_greeks(S, K, T, r, sigma, option_type=&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;call&quot;&lt;/span&gt;)
iv = implied_volatility(call, S, K, T, r, option_type=&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;call&quot;&lt;/span&gt;)
mc = monte_carlo_european_option(S, K, T, r, sigma, option_type=&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;call&quot;&lt;/span&gt;, random_state=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;42&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;209&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This is a better portfolio story than the original single-file approach because it separates pricing models from analysis notebooks.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;211&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The legacy &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;RiskOptima&lt;/code&gt; class methods are still preserved for backward compatibility, but the cleaner package-level API is now the preferred interface.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;213&quot; dir=&quot;auto&quot; id=&quot;project-5-credit-risk-model&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Project 5: Credit Risk Model&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;215&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The newest addition is the credit risk module.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;217&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; color: #d4d4d4; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEirXcq0jBGrz0DvI40RK8gLr5nzxFkJ0NOjS7dQktPjNrKsLqe0O8bMUwd4ZnGA4vMDLB6bTM1Ev80vi2XAw2LhlzSNENzc4AAtZtwG9-FmGJAWWkSfzUoh37pT5ymsAHBVC-7CXf-4excddOQWauiBBHbg8INAhCQB8ZNo3GVIAnh_bGokc0sJ5NC6KIo&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;675&quot; data-original-width=&quot;1200&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEirXcq0jBGrz0DvI40RK8gLr5nzxFkJ0NOjS7dQktPjNrKsLqe0O8bMUwd4ZnGA4vMDLB6bTM1Ev80vi2XAw2LhlzSNENzc4AAtZtwG9-FmGJAWWkSfzUoh37pT5ymsAHBVC-7CXf-4excddOQWauiBBHbg8INAhCQB8ZNo3GVIAnh_bGokc0sJ5NC6KIo=w640-h360&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;219&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Caption: The credit module adds a different risk lens: PD, LGD, EAD, expected loss, rating migration, Merton default probability, and simulated loss tails.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;221&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;This matters because credit risk is a different modelling domain from market risk and options. It shows that RiskOptima can cover more than asset returns and volatility.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;223&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The new &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;riskoptima.credit&lt;/code&gt; package includes:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;225&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;225&quot; dir=&quot;auto&quot;&gt;Logistic PD model helpers&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;226&quot; dir=&quot;auto&quot;&gt;PD prediction&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;227&quot; dir=&quot;auto&quot;&gt;Expected loss&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;228&quot; dir=&quot;auto&quot;&gt;Portfolio expected loss&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;229&quot; dir=&quot;auto&quot;&gt;Unexpected loss approximation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;230&quot; dir=&quot;auto&quot;&gt;Transition matrix validation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;231&quot; dir=&quot;auto&quot;&gt;Rating migration simulation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;232&quot; dir=&quot;auto&quot;&gt;Merton distance to default&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;233&quot; dir=&quot;auto&quot;&gt;Merton default probability&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;234&quot; dir=&quot;auto&quot;&gt;Credit loss Monte Carlo&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;235&quot; dir=&quot;auto&quot;&gt;Credit VaR&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;236&quot; dir=&quot;auto&quot;&gt;Credit CVaR&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;238&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Example:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-python&quot; data-line=&quot;240&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; pandas &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;as&lt;/span&gt; pd
&lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;from&lt;/span&gt; riskoptima.credit &lt;span class=&quot;hljs-keyword&quot; style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt; (
    portfolio_expected_loss,
    simulate_credit_losses,
    credit_var,
    credit_cvar,
    merton_pd,
)

portfolio = pd.DataFrame({
    &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;obligor&quot;&lt;/span&gt;: [&lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;A&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;B&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;C&quot;&lt;/span&gt;],
    &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;PD&quot;&lt;/span&gt;: [&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.01&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.025&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.04&lt;/span&gt;],
    &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;LGD&quot;&lt;/span&gt;: [&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.40&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.45&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.55&lt;/span&gt;],
    &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;EAD&quot;&lt;/span&gt;: [&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;1_000_000&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;750_000&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;500_000&lt;/span&gt;],
})

expected_loss = portfolio_expected_loss(portfolio)
losses = simulate_credit_losses(portfolio, n_sims=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;20_000&lt;/span&gt;, random_state=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;42&lt;/span&gt;)

var_99 = credit_var(losses, confidence=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.99&lt;/span&gt;)
cvar_99 = credit_cvar(losses, confidence=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.99&lt;/span&gt;)
merton_default_probability = merton_pd(
    asset_value=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;150&lt;/span&gt;,
    debt_face_value=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;100&lt;/span&gt;,
    asset_vol=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.25&lt;/span&gt;,
    risk_free_rate=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;0.03&lt;/span&gt;,
    maturity=&lt;span class=&quot;hljs-number&quot; style=&quot;color: #b8d7a3;&quot;&gt;1.0&lt;/span&gt;,
)
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;271&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;T&lt;/span&gt;his is the sort of feature that helps the project read like a complete risk platform rather than a collection of market-data notebooks.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;273&quot; dir=&quot;auto&quot; id=&quot;the-notebook-layer-still-matters&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;The Notebook Layer Still Matters&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;275&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;RiskOptima still includes notebooks because notebooks are useful for storytelling.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;277&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The current notebook set covers:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;279&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;279&quot; dir=&quot;auto&quot;&gt;Bond analytics&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;280&quot; dir=&quot;auto&quot;&gt;Portfolio optimization&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;281&quot; dir=&quot;auto&quot;&gt;Index / volatility divergence signals&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;282&quot; dir=&quot;auto&quot;&gt;Stochastic volatility models&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;283&quot; dir=&quot;auto&quot;&gt;SMA strategy backtesting&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;284&quot; dir=&quot;auto&quot;&gt;Options analytics&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;285&quot; dir=&quot;auto&quot;&gt;Core modular features&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;286&quot; dir=&quot;auto&quot;&gt;Credit risk modelling&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;288&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The important change is that notebooks are now demonstrations of package functionality, not the only place where the functionality exists.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;290&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That makes the project easier to test and easier to maintain.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;292&quot; dir=&quot;auto&quot; style=&quot;color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi791d-uCLYgxyr8eFqLd-OPFT7HQKbUEESJRVUWCdLZYLhvuAI_xywuEIT-bDCJaDktGxwmG6JjAmJ1_MPfzowJ__B4VaoAuCxucFuRU0a0VinAS0QxItd_i15kdOXpnNPT9gX6Lw0hEcul9-JLFsOpsRgzZy81U1dodPduqROscBdOu1oznTSFpatbGc&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;675&quot; data-original-width=&quot;1200&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi791d-uCLYgxyr8eFqLd-OPFT7HQKbUEESJRVUWCdLZYLhvuAI_xywuEIT-bDCJaDktGxwmG6JjAmJ1_MPfzowJ__B4VaoAuCxucFuRU0a0VinAS0QxItd_i15kdOXpnNPT9gX6Lw0hEcul9-JLFsOpsRgzZy81U1dodPduqROscBdOu1oznTSFpatbGc=w640-h360&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;294&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Caption: The notebooks are now the storytelling layer. The reusable code lives in the package modules.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;296&quot; dir=&quot;auto&quot; id=&quot;testing-and-reliability&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Testing and Reliability&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;298&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Another important update is test coverage.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;300&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;RiskOptima now includes tests around:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;302&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;302&quot; dir=&quot;auto&quot;&gt;Backtesting engine behaviour&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;303&quot; dir=&quot;auto&quot;&gt;Optimizer constraints&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;304&quot; dir=&quot;auto&quot;&gt;Factor risk model covariance&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;305&quot; dir=&quot;auto&quot;&gt;Credit risk calculations&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;306&quot; dir=&quot;auto&quot;&gt;Market risk reporting&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;307&quot; dir=&quot;auto&quot;&gt;Option pricing accuracy&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;308&quot; dir=&quot;auto&quot;&gt;Public API imports&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;309&quot; dir=&quot;auto&quot;&gt;Core dataclasses&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;310&quot; dir=&quot;auto&quot;&gt;Legacy analytics&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;311&quot; dir=&quot;auto&quot;&gt;Empty-trade SMA edge cases&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;313&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The project also validates all notebooks with execution checks. That is useful because quant notebooks often break quietly when market data changes, dependencies move, or a strategy produces no trades.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;315&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;In the latest pass, all eight notebooks executed successfully.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;317&quot; dir=&quot;auto&quot; id=&quot;what-this-project-demonstrates&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;What This Project Demonstrates&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;319&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;RiskOptima is designed to show practical quant engineering skill across several layers:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;321&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;321&quot; dir=&quot;auto&quot;&gt;Financial modelling&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;322&quot; dir=&quot;auto&quot;&gt;Python package design&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;323&quot; dir=&quot;auto&quot;&gt;Numerical methods&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;324&quot; dir=&quot;auto&quot;&gt;Data analysis&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;325&quot; dir=&quot;auto&quot;&gt;Risk reporting&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;326&quot; dir=&quot;auto&quot;&gt;Backtesting&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;327&quot; dir=&quot;auto&quot;&gt;Testing&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;328&quot; dir=&quot;auto&quot;&gt;Notebook-based communication&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;330&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That combination matters.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;332&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;A recruiter or interviewer does not just want to see that you can calculate a Sharpe ratio. They want to see that you can build something coherent, test it, explain it, and extend it.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;334&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;RiskOptima now tells that story much better than it did a year ago.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;336&quot; dir=&quot;auto&quot; id=&quot;what-i-would-add-next&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;What I Would Add Next&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;338&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The next highest-ROI improvements are not just more models. They are product and engineering polish:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;340&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;340&quot; dir=&quot;auto&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;340&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;Documentation site A small MkDocs or Sphinx site with API examples would make the project easier to navigate.&lt;/p&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;343&quot; dir=&quot;auto&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;343&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;Streamlit dashboard The market risk report layer is already dashboard-ready. A Streamlit app would make it visual and recruiter-friendly.&lt;/p&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;346&quot; dir=&quot;auto&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;346&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;CI notebook smoke tests Run unit tests on every push and execute a lightweight subset of notebooks on scheduled builds.&lt;/p&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;349&quot; dir=&quot;auto&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;349&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;Example datasets Add small synthetic datasets so every demo can run without live market data.&lt;/p&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;352&quot; dir=&quot;auto&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;352&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;Model validation pages For options, credit risk, and VaR, include known-value tests and methodology notes.&lt;/p&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;355&quot; dir=&quot;auto&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;355&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;Portfolio project landing page A single README section that maps each canonical quant project to notebooks, APIs, and tests.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;358&quot; dir=&quot;auto&quot; id=&quot;final-thoughts&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Final Thoughts&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;360&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The original RiskOptima Options Analysis Suite was useful because it solved a focused problem: options analysis with practical charts and workflows.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;362&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The updated RiskOptima is more ambitious.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;364&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;It is a quant finance toolkit that demonstrates how portfolio optimization, market risk, options analytics, backtesting, and credit risk can live together in one coherent Python project.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;366&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That is the direction I want the project to keep moving in: not just more notebooks, but a stronger bridge between research, engineering, and real-world risk analysis.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;368&quot; dir=&quot;auto&quot; id=&quot;image-assets-for-the-blogger-post&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;br /&gt;&lt;/h2&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/06/riskoptima-in-2026-turning-quant.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEgeVrgljGc9NWBXh8QttRj2sJ7ER_yLf9YTl83Wfq_V3GcndH83DR4ewPugVdxJxuR6zsZpASWRDUyG0EMc8AeqbEbKAk6VmMy0YrTzBxOPDdIBqmhPaHFzwhSUjn25f1EtufDoA2A7y4scpfjETks5LoeoZvuZeOgqTNjqyJpNypEY3YzOSK8-1Dprb6Y=s72-c" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-7723097082779285180</guid><pubDate>Sat, 13 Jun 2026 12:32:31 +0000</pubDate><atom:updated>2026-06-13T12:36:27.536+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AI</category><category domain="http://www.blogger.com/atom/ns#">copilot</category><category domain="http://www.blogger.com/atom/ns#">llm</category><category domain="http://www.blogger.com/atom/ns#">MiFID II</category><category domain="http://www.blogger.com/atom/ns#">Ollama</category><category domain="http://www.blogger.com/atom/ns#">regulatory</category><title>Building a Local MiFID Regulatory Copilot</title><description>&lt;p&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-family: verdana; font-size: 14px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-family: verdana; font-size: 14px;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6QH4PsiveWWTaddnf6nuv77BGyhIpWFB-S-EyLt360WcKUTt1uh2MIkVpqf4jzFcFLuXgiTdHR0DbIStRluOAds6e6_4csTzf5U_1DRhurYjdk9__RIjaFzMqHLeLDWFBqy2HTPRJCCz17dmIkmUdfHqRktmy13eZUSvQ-IKC9j_3EwimcvmpzJXO8vI/s1536/ChatGPT%20Image%20Jun%2013,%202026,%2001_33_47%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6QH4PsiveWWTaddnf6nuv77BGyhIpWFB-S-EyLt360WcKUTt1uh2MIkVpqf4jzFcFLuXgiTdHR0DbIStRluOAds6e6_4csTzf5U_1DRhurYjdk9__RIjaFzMqHLeLDWFBqy2HTPRJCCz17dmIkmUdfHqRktmy13eZUSvQ-IKC9j_3EwimcvmpzJXO8vI/s320/ChatGPT%20Image%20Jun%2013,%202026,%2001_33_47%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-family: verdana; font-size: 14px;&quot;&gt;I built this project for fun as a local-first regulatory copilot for MiFID II, MiFIR, UK MiFIR, transaction reporting, transparency, ARM/APA workflows, and source-backed analysis. The goal was not to build a generic chatbot. The goal was to build a reviewable regulatory workbench: a tool that starts from official documents, shows the evidence it used, and fails conservatively when the corpus is incomplete.&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The app now runs as a FastAPI service with a browser UI, local &lt;b&gt;Ollama&lt;/b&gt; generation, a manifest-driven regulatory corpus, hybrid retrieval, evidence scoring, citations, and a corpus explorer. It is designed to be deployed on a private server and exposed through Cloudflare Tunnel, while keeping the source documents and indexes under local control.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;color: #d4d4d4; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhmGwS5V7B83tLvbk6HQ9-t28XBOZTIWj6NW54wzWWpqdGwD6fLv14f4-DBcnAqW__2C4LXvoNgKkZZ-BYPi3Wd5rtfYQiXKuBtfSyelnmaIi0VbPB2B-dtyzER0r8o3XK6hKsVGqmgYNAndLgSoJe0_K30xR0BtpGWzcDwODXilMov3TZ6DFYpZI68SUU&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;912&quot; data-original-width=&quot;1149&quot; height=&quot;509&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhmGwS5V7B83tLvbk6HQ9-t28XBOZTIWj6NW54wzWWpqdGwD6fLv14f4-DBcnAqW__2C4LXvoNgKkZZ-BYPi3Wd5rtfYQiXKuBtfSyelnmaIi0VbPB2B-dtyzER0r8o3XK6hKsVGqmgYNAndLgSoJe0_K30xR0BtpGWzcDwODXilMov3TZ6DFYpZI68SUU=w640-h509&quot; width=&quot;640&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; id=&quot;why-local-first&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Why Local First&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Regulatory analysis has two constraints that are easy to underestimate.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;First, the answer must be traceable. If an assistant says a transaction is reportable, or that a transparency deferral may apply, a reviewer needs to see the exact document, page, article, and passage behind that claim.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Second, the source set must be controlled. MiFID and MiFIR materials exist across Level 1 legislation, RTS, ESMA Q&amp;amp;A, reporting instructions, XML schemas, FCA pages, FCA Handbook material, discussion papers, consultation papers, and policy statements. A useful assistant needs to know which sources are current, which are historical, which are proposals, and which jurisdiction they belong to.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Those constraints pushed the project toward retrieval-augmented generation instead of fine-tuning. Fine-tuning can help with style or workflow patterns, but it should not be the source of truth for current law. The law and guidance should live in an auditable corpus.&lt;/span&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; id=&quot;architecture&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Architecture&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The architecture has five layers:&lt;/span&gt;&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;22&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;22&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Source manifest&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Ingestion and chunking&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;24&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Keyword and vector indexing&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Route-aware retrieval and answer generation&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;UI, evidence quality, and corpus inspection&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;color: #d4d4d4; font-family: verdana; font-size: 14px;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiAqEjEgo0tDvHqtXRPlYyZhlX64uHbVLJfuuiT0kJXasZ59wzRvKzWM62CQmRfsaQwSOklZoEHM7rT9vmQyKquY3NimduiAOxHeSIxumqgvAllupMWuSx5pGaznNSATScG_ZPvrV48mmA3AdlRXvV6Owe98o6_5p3p1ePAkeDqTyLUIN4aFFYqwBIBn8o&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;443&quot; data-original-width=&quot;1592&quot; height=&quot;178&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiAqEjEgo0tDvHqtXRPlYyZhlX64uHbVLJfuuiT0kJXasZ59wzRvKzWM62CQmRfsaQwSOklZoEHM7rT9vmQyKquY3NimduiAOxHeSIxumqgvAllupMWuSx5pGaznNSATScG_ZPvrV48mmA3AdlRXvV6Owe98o6_5p3p1ePAkeDqTyLUIN4aFFYqwBIBn8o=w640-h178&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;color: #d4d4d4; font-family: verdana; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-size: 14px;&quot;&gt;The source manifest is the control plane. Each entry records the source ID, title, publisher, jurisdiction, regime, document type, domain tags, priority, status, official URL, and expected local path. The app does not silently scrape the internet at query time. Documents are downloaded into &lt;/span&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400;&quot;&gt;data/raw&lt;/span&gt;&lt;/code&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-size: 14px;&quot;&gt;, then parsed, chunked, and indexed.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;47&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;FastAPI serves the query endpoints and the static UI. Ollama provides local generation. The deployment model binds the API to &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400;&quot;&gt;127.0.0.1&lt;/span&gt;&lt;/code&gt;; Cloudflare Tunnel can expose it through HTTPS without opening an inbound firewall port. HTTP Basic authentication is loaded from an ignored local &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400;&quot;&gt;config/auth.yaml&lt;/span&gt;&lt;/code&gt;, and a public showcase should additionally use Cloudflare Access.&lt;/span&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;49&quot; dir=&quot;auto&quot; id=&quot;corpus-chunk-methodology&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Corpus Chunk Methodology&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;51&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The most important implementation detail is &lt;b&gt;chunking&lt;/b&gt;. Early versions of the corpus produced low-value chunks such as cover pages, titles, and fragments that looked meaningful in the UI but did not carry legal substance. That created bad retrieval: if the model receives weak context, it will either answer weakly or over-interpret the wrong passage.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;53&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The current &lt;b&gt;chunker &lt;/b&gt;is legal-boundary aware. It looks for headings such as:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400; font-family: verdana;&quot;&gt;Article 26&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400; font-family: verdana;&quot;&gt;Recital (12)&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;57&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400; font-family: verdana;&quot;&gt;CHAPTER IV&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;58&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400; font-family: verdana;&quot;&gt;SECTION 2&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400; font-family: verdana;&quot;&gt;ANNEX I&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;60&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400; font-family: verdana;&quot;&gt;Question 3&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;61&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400; font-family: verdana;&quot;&gt;Table 2&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;63&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;When a boundary is found, the chunker keeps the surrounding legal unit together where possible. It then enforces a size window from &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400;&quot;&gt;config/retrieval.yaml&lt;/span&gt;&lt;/code&gt;: chunks should be large enough to carry meaning, but small enough to fit into retrieval and prompt context. Oversized blocks are split by paragraph. Undersized blocks are merged with nearby legal blocks until they become useful.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Each chunk carries metadata:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400; font-family: verdana;&quot;&gt;source_id&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;68&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;document title and publisher&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;69&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;jurisdiction, regime, and domain tags&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;70&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;document type, priority, and status&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;71&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;page number&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;72&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;detected article, section, annex, question, or table&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;73&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;original extracted text&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;75&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The chunker also filters low-value front matter. Short policy-statement covers, tables of contents, and similar non-substantive fragments are excluded unless they contain strong legal signals. This matters because the corpus explorer is not just a debug tool; it shows exactly what the answer engine can see.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;77&quot; dir=&quot;auto&quot; style=&quot;color: #d4d4d4; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjOALKkT6SJ7H-v37iRbM9swH5_vrUlqSVczNiynqNb9ClCkG5zX9dtZYG5lRYChrI3KHLPkMY-IJGLpRzPFZoa3yaQKB5ioR97IgFfN5uwwgs4bu_rtOUAjsYpYjh72HJ_Q8Fbw2tLeKbWOV0Nw__uEstHGMk7YxjkMi8Apz0CFWHidsz101vCLw4gJm0&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;912&quot; data-original-width=&quot;1149&quot; height=&quot;509&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjOALKkT6SJ7H-v37iRbM9swH5_vrUlqSVczNiynqNb9ClCkG5zX9dtZYG5lRYChrI3KHLPkMY-IJGLpRzPFZoa3yaQKB5ioR97IgFfN5uwwgs4bu_rtOUAjsYpYjh72HJ_Q8Fbw2tLeKbWOV0Nw__uEstHGMk7YxjkMi8Apz0CFWHidsz101vCLw4gJm0=w640-h509&quot; width=&quot;640&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;79&quot; dir=&quot;auto&quot; id=&quot;retrieval-and-accuracy-controls&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Retrieval And Accuracy Controls&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;81&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Retrieval is hybrid. The app builds:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;83&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;83&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;a SQLite FTS5 keyword index for exact legal terms such as &lt;span style=&quot;color: #ffa400;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;Article 26&lt;/code&gt;, &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;RTS 22&lt;/code&gt;, &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;FIRDS&lt;/code&gt;, &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;deferral&lt;/code&gt;, or &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;APA&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;84&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;a local vector index for semantic matching&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;86&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The hybrid retriever merges both result sets, applies route filters, and adds ranking boosts for source priority, active status, consolidated source material, and domain-specific intent.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;88&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The router classifies each question by:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;90&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;90&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;jurisdiction: EU or UK&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;91&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;regime: MiFIR, MiFID II, or UK MiFIR&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;domain: transaction reporting, transparency, reference data, algorithmic trading, order records, or overview&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;94&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;That route is important. A UK transparency question should not accidentally retrieve EU RTS material unless the user asks for a comparison. A MiFID overview should prefer Level 1 Directive scope material instead of a narrow RTS. A transaction reportability question should route to MiFIR Article 26 and RTS 22, even if a user casually says &quot;under MiFID II&quot;.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;That last example became a useful design test. A question like &quot;What information is needed to determine transaction reportability under MiFID II?&quot; was initially pulling in RTS 25 clock synchronisation because RTS 25 is MiFID II material and includes transaction-adjacent wording. The fix was not to hard-code one answer. The fix was to improve routing and retrieval:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;98&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;98&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;transaction reportability now routes to MiFIR Article 26 / RTS 22&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;99&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;reportability retrieval seeds canonical chunks from MiFIR Article 26, RTS 22 Article 1, RTS 22 Article 2, and RTS 22 Table 2&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;100&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;RTS 25 clock synchronisation is penalised for reportability questions unless the user asks about clocks, timestamps, or RTS 25&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;101&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;a regression test locks this behaviour&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;103&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;This is the general pattern for accuracy: make the route explicit, prefer canonical sources, show citations, and add tests for retrieval failures.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;103&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgU4vX6ilEfhexa8H711fDWfaQC69dcoqBZnQmW4bwqoaC0OEYvmabnteS66BGhhZUa6z-_Wm2M1jROfWgV0TsTGPH7gKlWX3FKPQg33ZEjYOzlSTxebS9xoVoywPzTacOfdnu6aSFEKqkE8v0x32YqQiGvRtbhiEsGOpNohikdKJfg7qLYTk6yXk4Of0Y&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;889&quot; data-original-width=&quot;1146&quot; height=&quot;497&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgU4vX6ilEfhexa8H711fDWfaQC69dcoqBZnQmW4bwqoaC0OEYvmabnteS66BGhhZUa6z-_Wm2M1jROfWgV0TsTGPH7gKlWX3FKPQg33ZEjYOzlSTxebS9xoVoywPzTacOfdnu6aSFEKqkE8v0x32YqQiGvRtbhiEsGOpNohikdKJfg7qLYTk6yXk4Of0Y=w640-h497&quot; width=&quot;640&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj52DQd0pef0CRk9dZUiNDZd-9pJmqk3Vt-K9beGDsgdrli65XvaqVENnKEJhKWxU4VhFMaC4JXbULeh91OqSZkUTBdjnmiIb6AUzBb8aXILos_7IfY3s5gBr0l8gdt-HS_0_z_Xc51Fdnosoo41wRK8-wZQNiVGo3tqzxrZCbyFDVt02XZPesiT3uZuhI&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;893&quot; data-original-width=&quot;1118&quot; height=&quot;512&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEj52DQd0pef0CRk9dZUiNDZd-9pJmqk3Vt-K9beGDsgdrli65XvaqVENnKEJhKWxU4VhFMaC4JXbULeh91OqSZkUTBdjnmiIb6AUzBb8aXILos_7IfY3s5gBr0l8gdt-HS_0_z_Xc51Fdnosoo41wRK8-wZQNiVGo3tqzxrZCbyFDVt02XZPesiT3uZuhI=w640-h512&quot; width=&quot;640&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;105&quot; dir=&quot;auto&quot; id=&quot;how-an-answer-is-derived&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;How An Answer Is Derived&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;107&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;When a user asks a question, the app does the following:&lt;/span&gt;&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;109&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;109&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Classifies the question into jurisdiction, regime, and domain.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;110&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Expands the retrieval query with domain-specific terms.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;111&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Retrieves source chunks using keyword search, vector search, metadata filters, and seeded canonical evidence.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;112&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Builds a prompt containing only the retrieved context and route assumptions.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;113&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Calls the local Ollama model (using &lt;b&gt;gemma3n&lt;/b&gt;).&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;114&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Converts the generated answer into a deterministic report format.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Builds citations directly from the retrieved chunks.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;116&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Scores the evidence quality and shows warnings.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;118&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The deterministic formatter is deliberate. LLMs are useful for summarising and connecting evidence, but the outer structure should be stable. The app controls the headings, assessment status, citation list, required data fields, missing facts, systems impact, validation rules, and confidence statement. This avoids UI-breaking formatting drift and keeps reviewer-facing output predictable.&lt;/span&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;120&quot; dir=&quot;auto&quot; id=&quot;evidence-quality&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Evidence Quality&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;122&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Every answer gets an evidence-quality report. The score considers:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;124&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;124&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;number of retrieved sources&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;125&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;number of retrieved chunks&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;126&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;source priority&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;127&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;document type&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;128&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;source status&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;jurisdiction match&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;130&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;regime match&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;131&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;domain match&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The UI treats this as a gate, not decoration. Low means the answer should not be relied on. Medium means draft use only. High means the evidence base is strong enough for analyst review, still subject to compliance sign-off.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Citations show the source ID, title, document type, page, article or section when available, and a short source preview. Retrieved chunks are also listed so a reviewer can inspect what the model saw.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjFZunpHCRQb3uhTIq6L83RtB7le21tqAM3PohNHQaw5gMSlQ6jzIHYP-UJLdY0iWeeN_fW5LKcc_ds1xn2UZcChar29I4X3b9ic3g6FAPspgsqG4E4UhMmxL7SlBG_0i-7dO_4GDtFbkY0TxMt6rj9KT13Gmf4JCn05zyl0ygQVPXkDVTV-dnvHZHeO8A&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;879&quot; data-original-width=&quot;397&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjFZunpHCRQb3uhTIq6L83RtB7le21tqAM3PohNHQaw5gMSlQ6jzIHYP-UJLdY0iWeeN_fW5LKcc_ds1xn2UZcChar29I4X3b9ic3g6FAPspgsqG4E4UhMmxL7SlBG_0i-7dO_4GDtFbkY0TxMt6rj9KT13Gmf4JCn05zyl0ygQVPXkDVTV-dnvHZHeO8A=w288-h640&quot; width=&quot;288&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;137&quot; dir=&quot;auto&quot; id=&quot;the-corpus-explorer&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The Corpus Explorer&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;139&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The corpus explorer makes the knowledge base inspectable. It answers questions like:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;141&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;141&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Which official files are loaded?&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;142&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Which sources are missing?&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;How many chunks were produced per source?&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;144&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;What exact text is available to retrieval?&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;145&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Which article, page, or table did a chunk come from?&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;147&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;This is essential for trust. When an answer looks wrong, the first question should not be &quot;why did the model say that?&quot; It should be &quot;what evidence did retrieval give the model?&quot; The corpus explorer gives that answer directly.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;147&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEidWwO4lyOBxKEY8F-4VnyUq5vmx8Q-C2oPwmMrwPHKi0DfPtxRrBGmc9kf2DySzV8U7aK8wk2NBmulUJJSbHf8Jknz46TgGDyvu5xG5WXf-irWMoRcAWNjFOAcfKfOVvtvBX-kOtIxLjmwDKEdZfWU6BVvjjYnk-UqD_ZzdVdxFbv3mir59uWTc0yu0qI&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;766&quot; data-original-width=&quot;1131&quot; height=&quot;434&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEidWwO4lyOBxKEY8F-4VnyUq5vmx8Q-C2oPwmMrwPHKi0DfPtxRrBGmc9kf2DySzV8U7aK8wk2NBmulUJJSbHf8Jknz46TgGDyvu5xG5WXf-irWMoRcAWNjFOAcfKfOVvtvBX-kOtIxLjmwDKEdZfWU6BVvjjYnk-UqD_ZzdVdxFbv3mir59uWTc0yu0qI=w640-h434&quot; width=&quot;640&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;149&quot; dir=&quot;auto&quot; id=&quot;deployment-model&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Deployment Model&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;151&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The deployment shape is intentionally small:&lt;/span&gt;&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;153&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;153&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Clone the repository on the server. (Source code is still private, if you want to see it, reach out)&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;154&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Create &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400;&quot;&gt;config/auth.yaml&lt;/span&gt;&lt;/code&gt; locally and keep it out of git.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;155&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Add the official source files under the paths listed in &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400;&quot;&gt;config/source_manifest.yaml&lt;/span&gt;&lt;/code&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;156&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Run manifest validation.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;157&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Build the corpus.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;158&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Build the indexes.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;159&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Start FastAPI bound to &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #ffa400;&quot;&gt;127.0.0.1&lt;/span&gt;&lt;/code&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;160&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Expose it through Cloudflare Tunnel.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The current helper script can start the API and quick Cloudflare tunnel for demos. For a stable external setup, use a named Cloudflare Tunnel, a stable hostname, Cloudflare Access, log rotation, dependency scanning, rate limits, and a regular corpus refresh process.&lt;/span&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;164&quot; dir=&quot;auto&quot; id=&quot;testing-strategy&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Testing Strategy&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;166&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The test suite covers the mechanics that matter for this kind of app:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;168&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;168&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;source manifest validation&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;169&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;chunk metadata extraction&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;170&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;retrieval filtering&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;171&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;route classification&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;172&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;overview retrieval for MiFID and MiFIR&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;173&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;transaction reportability routing to MiFIR / RTS 22&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;174&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;evidence scoring&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;175&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;acceptance questions with expected source IDs and expected terms&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;177&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The acceptance file is intentionally simple: each question defines the expected jurisdiction, regime, domain, minimum evidence level, expected sources, and expected terms. This provides a repeatable sanity check without requiring the LLM to produce byte-identical prose.&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;179&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;For a regulatory copilot, this is the right kind of test. The generated wording can vary, but the evidence path should be stable.&lt;/span&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;181&quot; dir=&quot;auto&quot; id=&quot;what-this-enables&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;What This Enables&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;183&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The result is a local regulatory copilot that can:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;185&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;185&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;answer MiFID / MiFIR reporting questions from local official sources&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;186&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;separate EU and UK material&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;187&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;cite source chunks&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;188&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;flag weak evidence&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;189&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;expose the corpus for review&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;190&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;support controlled external demos through Cloudflare&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;191&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;grow by adding new manifest sources and domain-specific retrieval seeds&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;193&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The app is usable today as a showcase and analyst draft tool. It is not a replacement for legal or compliance sign-off. The value is that it makes the evidence path visible and testable, which is exactly what a regulatory assistant needs before it can become operationally useful.&lt;/span&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;195&quot; dir=&quot;auto&quot; id=&quot;next-extensions&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;Next Extensions&lt;/span&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;197&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;The strongest next improvements would be:&lt;/span&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;199&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;199&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;replace fallback hash embeddings with a production embedding model&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;200&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;add a reranker for better long-document retrieval&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;201&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;improve table extraction for RTS field tables and FCA policy statements&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;202&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;add source freshness checks and supersession metadata&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;203&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;add Cloudflare Access and request rate limiting for public demos&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;204&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;add structured audit logs for questions, routes, retrieved chunks, and evidence scores&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;205&quot; dir=&quot;auto&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;build workflow-specific dashboards for transaction reporting, transparency, ARMs, APAs, and exception management&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;207&quot; dir=&quot;auto&quot; style=&quot;font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana;&quot;&gt;&lt;b&gt;The architecture is intentionally extensible&lt;/b&gt;: new source types enter through the manifest, new documents become chunks, chunks become searchable evidence, and route-specific retrieval rules can be added without changing the UI contract.&lt;/span&gt;&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/06/building-local-mifid-regulatory-copilot.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6QH4PsiveWWTaddnf6nuv77BGyhIpWFB-S-EyLt360WcKUTt1uh2MIkVpqf4jzFcFLuXgiTdHR0DbIStRluOAds6e6_4csTzf5U_1DRhurYjdk9__RIjaFzMqHLeLDWFBqy2HTPRJCCz17dmIkmUdfHqRktmy13eZUSvQ-IKC9j_3EwimcvmpzJXO8vI/s72-c/ChatGPT%20Image%20Jun%2013,%202026,%2001_33_47%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-7987079197259748214</guid><pubDate>Sun, 07 Jun 2026 14:44:48 +0000</pubDate><atom:updated>2026-06-07T14:44:48.527+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Cloudflare</category><category domain="http://www.blogger.com/atom/ns#">external</category><category domain="http://www.blogger.com/atom/ns#">local web app</category><category domain="http://www.blogger.com/atom/ns#">tunnel</category><title>Exposing a Local Web App With a Cloudflare Tunnel</title><description>&lt;h1 class=&quot;code-line code-active-line&quot; data-line=&quot;0&quot; dir=&quot;auto&quot; id=&quot;exposing-a-local-web-app-with-a-cloudflare-tunnel&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 0px; padding-bottom: 0.3em;&quot;&gt;&lt;span style=&quot;font-size: 14px; font-weight: normal;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0qqNoV62SyqUQbZ6GjkU0Tcj3WXFRHqrPatfwMNIVgGnEqfyRftsql30AeDVgn5yLD8LfMCMBc5quDO-rTdXYzA6KFNpd6z0u9cbpZDv4fWh-DQLJiZqYuPofMydizGuV86IHs0UDL-pSxIOkcRTXawQTVeFEcmsN1XbSZowsi_fmpA8Sf8FSVaaeKg8/s1672/ChatGPT%20Image%20Jun%207,%202026,%2003_44_07%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;941&quot; data-original-width=&quot;1672&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0qqNoV62SyqUQbZ6GjkU0Tcj3WXFRHqrPatfwMNIVgGnEqfyRftsql30AeDVgn5yLD8LfMCMBc5quDO-rTdXYzA6KFNpd6z0u9cbpZDv4fWh-DQLJiZqYuPofMydizGuV86IHs0UDL-pSxIOkcRTXawQTVeFEcmsN1XbSZowsi_fmpA8Sf8FSVaaeKg8/s320/ChatGPT%20Image%20Jun%207,%202026,%2003_44_07%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;When you want to open a local web app from a phone, tablet, teammate&#39;s machine, or temporary external device, a Cloudflare Tunnel is a simple way to expose it without changing router settings. It gives you a public HTTPS URL that forwards traffic back to a local development server.&lt;/span&gt;&lt;/h1&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;No port forwarding, no public IP, no DNS setup, and no inbound firewall exposure are required for the quick version.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; id=&quot;what-we-are-building&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;What We Are Building&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;A common local full-stack app has two processes:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot;&gt;Frontend: Vite on &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;http://127.0.0.1:5173&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;11&quot; dir=&quot;auto&quot;&gt;Backend API: for example ASP.NET Core, Node, Python, or another API on &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;http://127.0.0.1:5069&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;13&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The external browser only talks to the public Cloudflare URL. Cloudflare forwards that traffic to Vite, and Vite proxies backend calls to the local API:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;15&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;External browser
  -&amp;gt; https://random-name.trycloudflare.com
  -&amp;gt; Cloudflare edge
  -&amp;gt; cloudflared on this machine
  -&amp;gt; Vite dev server on 127.0.0.1:5173
  -&amp;gt; /api and optional WebSocket routes proxied to the backend on 127.0.0.1:5069
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;24&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For short-lived demos this is ideal. The URL is random, disposable, HTTPS-enabled, and does not require a Cloudflare account.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; id=&quot;why-cloudflare-tunnel&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Why Cloudflare Tunnel&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The normal LAN setup works if your phone and laptop are on the same WiFi, but it can fail because of hotel networks, mobile hotspots, VPNs, firewall rules, or router isolation.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;A tunnel avoids that by making an outbound connection from your machine to Cloudflare. Your laptop does not need to accept inbound internet traffic directly.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Cloudflare calls this short-lived mode a &lt;strong&gt;Quick Tunnel&lt;/strong&gt; or &lt;strong&gt;TryCloudflare&lt;/strong&gt; tunnel. The command looks like this:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;cloudflared tunnel &lt;span class=&quot;hljs-literal&quot;&gt;--url&lt;/span&gt; http://localhost:&lt;span class=&quot;hljs-number&quot;&gt;5173&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Cloudflare then prints a URL like:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;https://some-random-words.trycloudflare.com
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That is the URL you open from the external device.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;46&quot; dir=&quot;auto&quot; id=&quot;step-1-install-cloudflared&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 1: Install &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cloudflared&lt;/code&gt;&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;48&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Download &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cloudflared&lt;/code&gt; from Cloudflare:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot;&gt;&lt;a data-href=&quot;https://developers.cloudflare.com/tunnel/downloads/&quot; href=&quot;https://developers.cloudflare.com/tunnel/downloads/&quot; style=&quot;text-decoration: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;https://developers.cloudflare.com/tunnel/downloads/&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;On Windows, you can put &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cloudflared.exe&lt;/code&gt; somewhere simple, for example:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;C:\Tools\cloudflared\cloudflared.exe
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;58&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Then either add that folder to &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;PATH&lt;/code&gt;, or run it with the full path:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;60&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;C:\Tools\cloudflared\cloudflared.exe &lt;span class=&quot;hljs-literal&quot;&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;64&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;If it prints a version, the binary is ready.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;66&quot; dir=&quot;auto&quot; id=&quot;step-2-start-the-backend-api&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 2: Start the Backend API&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;68&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Start whatever backend your app uses. For example, a .NET API might look like this:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;70&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt; C:\repo\my&lt;span class=&quot;hljs-literal&quot;&gt;-app&lt;/span&gt;
dotnet run &lt;span class=&quot;hljs-literal&quot;&gt;--project&lt;/span&gt; src\MyApp.Api\MyApp.Api.csproj &lt;span class=&quot;hljs-literal&quot;&gt;--launch-profile&lt;/span&gt; http
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;75&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Or a Node API might look like this:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;77&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt; C:\repo\my&lt;span class=&quot;hljs-literal&quot;&gt;-app&lt;/span&gt;\backend
npm run dev
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;82&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Check the backend health endpoint if you have one:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;84&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;Invoke-WebRequest&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-UseBasicParsing&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-Uri&lt;/span&gt; http://&lt;span class=&quot;hljs-number&quot;&gt;127.0&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;0.1&lt;/span&gt;:&lt;span class=&quot;hljs-number&quot;&gt;5069&lt;/span&gt;/api/health
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;88&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;You want HTTP 200.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;90&quot; dir=&quot;auto&quot; id=&quot;step-3-start-the-frontend&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 3: Start the Frontend&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;In another terminal:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;94&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt; C:\repo\my&lt;span class=&quot;hljs-literal&quot;&gt;-app&lt;/span&gt;\frontend
npm run dev:lan
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;99&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For a Vite app, &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;dev:lan&lt;/code&gt; typically runs Vite with:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;101&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;vite --host 0.0.0.0
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;105&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That makes the dev server reachable beyond only &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;localhost&lt;/code&gt;. The Cloudflare tunnel can still point at &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;127.0.0.1&lt;/code&gt;, but LAN binding also keeps the same command useful for direct local-network testing.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;107&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Check the frontend locally:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;109&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;Invoke-WebRequest&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-UseBasicParsing&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-Uri&lt;/span&gt; http://&lt;span class=&quot;hljs-number&quot;&gt;127.0&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;0.1&lt;/span&gt;:&lt;span class=&quot;hljs-number&quot;&gt;5173&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;113&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Again, you want HTTP 200.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot; id=&quot;step-4-start-the-cloudflare-tunnel&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Step 4: Start the Cloudflare Tunnel&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;In a third terminal:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;119&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;cloudflared tunnel &lt;span class=&quot;hljs-literal&quot;&gt;--url&lt;/span&gt; http://&lt;span class=&quot;hljs-number&quot;&gt;127.0&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;0.1&lt;/span&gt;:&lt;span class=&quot;hljs-number&quot;&gt;5173&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;123&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;If &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cloudflared&lt;/code&gt; is not on &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;PATH&lt;/code&gt;, use the full path:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;125&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;C:\Tools\cloudflared\cloudflared.exe tunnel &lt;span class=&quot;hljs-literal&quot;&gt;--url&lt;/span&gt; http://&lt;span class=&quot;hljs-number&quot;&gt;127.0&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;0.1&lt;/span&gt;:&lt;span class=&quot;hljs-number&quot;&gt;5173&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;After a few seconds, &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cloudflared&lt;/code&gt; prints a public URL ending in:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;131&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;.trycloudflare.com
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Open that URL from the external device.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;137&quot; dir=&quot;auto&quot; id=&quot;why-we-tunnel-the-frontend-not-the-backend&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Why We Tunnel the Frontend, Not the Backend&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;139&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For a React/Vite app backed by an API, expose Vite on port &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;5173&lt;/code&gt;, not the backend API directly.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;141&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That matters because the browser app loads frontend assets from Vite, and Vite can proxy backend traffic:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;/api&lt;/code&gt; goes to the backend API&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;144&quot; dir=&quot;auto&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;/hubs&lt;/code&gt;, &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;/ws&lt;/code&gt;, or another WebSocket route goes to the backend when needed&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;146&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;So from the external browser&#39;s point of view, everything appears to come from the same public origin:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;148&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;https://random-name.trycloudflare.com
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;152&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That avoids mixed-origin problems for normal API calls and WebSockets.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;154&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;If you only need to expose an API without a frontend, point the tunnel directly at the API instead:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;156&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;cloudflared tunnel &lt;span class=&quot;hljs-literal&quot;&gt;--url&lt;/span&gt; http://&lt;span class=&quot;hljs-number&quot;&gt;127.0&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;0.1&lt;/span&gt;:&lt;span class=&quot;hljs-number&quot;&gt;5069&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;160&quot; dir=&quot;auto&quot; id=&quot;vite-proxy-requirement&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Vite Proxy Requirement&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For a frontend + backend setup, the frontend dev server should proxy API and WebSocket requests to the backend. In a Vite app, this lives in &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;vite.config.ts&lt;/code&gt;.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;164&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Conceptually it needs this:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-ts&quot; data-line=&quot;166&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;server&lt;/span&gt;: {
  &lt;span class=&quot;hljs-attr&quot;&gt;proxy&lt;/span&gt;: {
    &lt;span class=&quot;hljs-string&quot;&gt;&#39;/api&#39;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;http://127.0.0.1:5069&#39;&lt;/span&gt;,
    &lt;span class=&quot;hljs-string&quot;&gt;&#39;/hubs&#39;&lt;/span&gt;: {
      &lt;span class=&quot;hljs-attr&quot;&gt;target&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;http://127.0.0.1:5069&#39;&lt;/span&gt;,
      &lt;span class=&quot;hljs-attr&quot;&gt;ws&lt;/span&gt;: &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;,
    },
  },
}
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;178&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The important bit is &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;ws: true&lt;/code&gt; for any WebSocket route. For example, SignalR often uses &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;/hubs&lt;/code&gt;, while other apps might use &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;/ws&lt;/code&gt;, &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;/socket&lt;/code&gt;, or &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;/socket.io&lt;/code&gt;.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;180&quot; dir=&quot;auto&quot; id=&quot;backend-cors&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Backend CORS&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;182&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;In this setup, CORS is less painful because the external browser calls the Cloudflare URL, and Vite proxies backend calls server-side during development.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;184&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Still, your backend CORS policy should support the local dev origins used by Vite:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;186&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;http://localhost:5173
http://127.0.0.1:5173
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;191&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For direct LAN testing, you may also want to allow private network origins on port &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;5173&lt;/code&gt;, such as:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;193&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;http://192.168.x.x:5173
http://10.x.x.x:5173
http://172.16.x.x:5173
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;199&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That is separate from the Cloudflare tunnel, but useful when testing directly on WiFi.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;201&quot; dir=&quot;auto&quot; id=&quot;quick-tunnel-vs-named-tunnel&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Quick Tunnel vs Named Tunnel&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;203&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The command above creates a Quick Tunnel:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;205&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;cloudflared tunnel &lt;span class=&quot;hljs-literal&quot;&gt;--url&lt;/span&gt; http://&lt;span class=&quot;hljs-number&quot;&gt;127.0&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;0.1&lt;/span&gt;:&lt;span class=&quot;hljs-number&quot;&gt;5173&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;209&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;That is best for:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;211&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;211&quot; dir=&quot;auto&quot;&gt;A temporary demo&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;212&quot; dir=&quot;auto&quot;&gt;Sharing a local app briefly&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;213&quot; dir=&quot;auto&quot;&gt;Testing from a phone or tablet&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;214&quot; dir=&quot;auto&quot;&gt;Avoiding Cloudflare account setup&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;216&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;The tradeoffs:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;218&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;218&quot; dir=&quot;auto&quot;&gt;The URL is random.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;219&quot; dir=&quot;auto&quot;&gt;The URL changes when you restart the tunnel.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;220&quot; dir=&quot;auto&quot;&gt;It is not meant to be permanent infrastructure.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;221&quot; dir=&quot;auto&quot;&gt;Anyone with the URL can try to access it.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;223&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;For a longer-running setup, use a named tunnel with a Cloudflare account and your own domain. That gives you stable DNS, access policies, service installation, and better operational control.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;225&quot; dir=&quot;auto&quot; id=&quot;security-notes&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Security Notes&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;227&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Treat the random URL as public.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;229&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;It is obscure, but not authentication. For a quick demo that may be enough. For anything long-lived, add one of:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;231&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;231&quot; dir=&quot;auto&quot;&gt;Cloudflare Access&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;232&quot; dir=&quot;auto&quot;&gt;App-level authentication&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;233&quot; dir=&quot;auto&quot;&gt;A private token in the app&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;234&quot; dir=&quot;auto&quot;&gt;A named tunnel behind your own domain&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;236&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Also remember that the local app is still your development instance. If it has admin endpoints, debug tools, seed data, or destructive buttons, the tunnel exposes those too.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;238&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;As a rule of thumb, a Quick Tunnel is fine for short private checks, but it should not be left running indefinitely without authentication.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;240&quot; dir=&quot;auto&quot; id=&quot;troubleshooting&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Troubleshooting&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;242&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;If the Cloudflare URL opens but the page is blank:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;244&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;244&quot; dir=&quot;auto&quot;&gt;Confirm Vite is running on &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;5173&lt;/code&gt;.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;245&quot; dir=&quot;auto&quot;&gt;Open &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;http://127.0.0.1:5173&lt;/code&gt; locally.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;246&quot; dir=&quot;auto&quot;&gt;Check the Vite terminal for errors.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;248&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;If API data does not load:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;250&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;250&quot; dir=&quot;auto&quot;&gt;Confirm the backend is running on &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;5069&lt;/code&gt;.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;251&quot; dir=&quot;auto&quot;&gt;Open &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;http://127.0.0.1:5069/api/health&lt;/code&gt;.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;252&quot; dir=&quot;auto&quot;&gt;Check that Vite is proxying &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;/api&lt;/code&gt; to the backend.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;254&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;If WebSockets do not connect:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;256&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;256&quot; dir=&quot;auto&quot;&gt;Confirm your WebSocket route is proxied with &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;ws: true&lt;/code&gt;.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;257&quot; dir=&quot;auto&quot;&gt;Check browser dev tools for WebSocket errors.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;258&quot; dir=&quot;auto&quot;&gt;Restart Vite and &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cloudflared&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;260&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;If the tunnel command starts but no URL appears:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;262&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;262&quot; dir=&quot;auto&quot;&gt;Check your internet connection.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;263&quot; dir=&quot;auto&quot;&gt;Try a newer &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cloudflared&lt;/code&gt; binary.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;264&quot; dir=&quot;auto&quot;&gt;Make sure no local Cloudflare config is interfering with Quick Tunnels.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;266&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;If the URL stops working:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;268&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;268&quot; dir=&quot;auto&quot;&gt;Check that the &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cloudflared&lt;/code&gt; process is still running.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;269&quot; dir=&quot;auto&quot;&gt;Quick Tunnel URLs are tied to that running process.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;270&quot; dir=&quot;auto&quot;&gt;Restarting the process normally creates a new URL.&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;272&quot; dir=&quot;auto&quot; id=&quot;useful-commands&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;Useful Commands&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;274&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Backend:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;276&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt; C:\repo\my&lt;span class=&quot;hljs-literal&quot;&gt;-app&lt;/span&gt;
dotnet run &lt;span class=&quot;hljs-literal&quot;&gt;--project&lt;/span&gt; src\MyApp.Api\MyApp.Api.csproj &lt;span class=&quot;hljs-literal&quot;&gt;--launch-profile&lt;/span&gt; http
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;281&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Frontend:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;283&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt; C:\repo\my&lt;span class=&quot;hljs-literal&quot;&gt;-app&lt;/span&gt;\frontend
npm run dev:lan
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;288&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Tunnel:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;290&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;cloudflared tunnel &lt;span class=&quot;hljs-literal&quot;&gt;--url&lt;/span&gt; http://&lt;span class=&quot;hljs-number&quot;&gt;127.0&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;0.1&lt;/span&gt;:&lt;span class=&quot;hljs-number&quot;&gt;5173&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;294&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px;&quot;&gt;Health checks:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;296&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;Invoke-WebRequest&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-UseBasicParsing&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-Uri&lt;/span&gt; http://&lt;span class=&quot;hljs-number&quot;&gt;127.0&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;0.1&lt;/span&gt;:&lt;span class=&quot;hljs-number&quot;&gt;5069&lt;/span&gt;/api/health
&lt;span class=&quot;hljs-built_in&quot;&gt;Invoke-WebRequest&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-UseBasicParsing&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;-Uri&lt;/span&gt; http://&lt;span class=&quot;hljs-number&quot;&gt;127.0&lt;/span&gt;.&lt;span class=&quot;hljs-number&quot;&gt;0.1&lt;/span&gt;:&lt;span class=&quot;hljs-number&quot;&gt;5173&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;301&quot; dir=&quot;auto&quot; id=&quot;references&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em;&quot;&gt;References&lt;/h2&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;303&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;303&quot; dir=&quot;auto&quot;&gt;Cloudflare Quick Tunnels: &lt;a data-href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/&quot; href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/&quot; style=&quot;text-decoration: none;&quot;&gt;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;304&quot; dir=&quot;auto&quot;&gt;Cloudflare &lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cloudflared&lt;/code&gt; downloads: &lt;a data-href=&quot;https://developers.cloudflare.com/tunnel/downloads/&quot; href=&quot;https://developers.cloudflare.com/tunnel/downloads/&quot; style=&quot;text-decoration: none;&quot;&gt;https://developers.cloudflare.com/tunnel/downloads/&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;305&quot; dir=&quot;auto&quot;&gt;Cloudflare Tunnel configuration: &lt;a data-href=&quot;https://developers.cloudflare.com/tunnel/configuration/&quot; href=&quot;https://developers.cloudflare.com/tunnel/configuration/&quot; style=&quot;text-decoration: none;&quot;&gt;https://developers.cloudflare.com/tunnel/configuration/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/06/exposing-local-web-app-with-cloudflare.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0qqNoV62SyqUQbZ6GjkU0Tcj3WXFRHqrPatfwMNIVgGnEqfyRftsql30AeDVgn5yLD8LfMCMBc5quDO-rTdXYzA6KFNpd6z0u9cbpZDv4fWh-DQLJiZqYuPofMydizGuV86IHs0UDL-pSxIOkcRTXawQTVeFEcmsN1XbSZowsi_fmpA8Sf8FSVaaeKg8/s72-c/ChatGPT%20Image%20Jun%207,%202026,%2003_44_07%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-2220041510035337352</guid><pubDate>Sun, 19 Apr 2026 06:33:00 +0000</pubDate><atom:updated>2026-04-19T06:50:24.674+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cloning studio</category><category domain="http://www.blogger.com/atom/ns#">local voice</category><category domain="http://www.blogger.com/atom/ns#">Python</category><category domain="http://www.blogger.com/atom/ns#">qwen3</category><title>Building a Local Voice Cloning Studio That Actually Runs on My Machine</title><description>&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg4rV9Sh3XmT5Cvdese1wY7GATOy0mXbzga6pP7WIXMfOrCILNT5jUWw1neCTsTqzpm_aGMJaOLX991wla6VmZtRu3UOcl_ri2h-7blx245iQxymuazIIpQARp0ymLuAytf5jUoCnlKw-kJ6gTxvLhUX-dfwdcozVJDW8YC6QosFyhd9DZczeKTniQNcNQ&quot; style=&quot;clear: left; display: inline; float: left; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1024&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg4rV9Sh3XmT5Cvdese1wY7GATOy0mXbzga6pP7WIXMfOrCILNT5jUWw1neCTsTqzpm_aGMJaOLX991wla6VmZtRu3UOcl_ri2h-7blx245iQxymuazIIpQARp0ymLuAytf5jUoCnlKw-kJ6gTxvLhUX-dfwdcozVJDW8YC6QosFyhd9DZczeKTniQNcNQ=w320-h320&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;2&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I wanted a local voice cloning workflow that felt like a real product, not a notebook demo.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The goal was simple: record or upload a short reference clip, create a reusable voice profile, type arbitrary text, synthesize speech locally, and keep every file on my own machine. No accounts, no cloud voice API, no remote inference.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The result is&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #7f6000;&quot;&gt;&lt;a href=&quot;https://github.com/JordiCorbilla/local-voice-studio&quot;&gt;local-voice-studio&lt;/a&gt;&lt;/span&gt;&lt;/code&gt;: a React and FastAPI application with local profile management, reference audio handling, generation history, diagnostics, and pluggable local TTS engines.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; id=&quot;the-product-shape&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Product Shape&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The app is built around a few core workflows.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;You can create multiple voice profiles, each with notes, language preference, tags, saved reference clips, a primary clip, and synthesis defaults. Reference clips can come from browser microphone recording or from uploaded audio files. The backend normalizes every clip to a model-friendly WAV file, stores metadata in SQLite, and keeps the original upload on disk.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The generation page is a focused workspace: choose a profile, enter text, optionally provide delivery instructions, tweak advanced settings, generate audio, and then preview or download the WAV result. Every generation is stored in history with status, parameters, input text, output path, and errors if something fails.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The settings page shows the local runtime state: active engine, model name, GPU detection, FFmpeg availability, directories in use, and whether local transcription is available.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Everything lives under the local&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;span style=&quot;color: #7f6000;&quot;&gt;data/&lt;/span&gt;&lt;/code&gt;&amp;nbsp;directory.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiKONn2eGMehvA4CkbVPbvEOvvfKcN93yvObODdRKzcrpvL8A_W--Z131OaXLBYqDWST37GlAht5YfiW3W6pS8ctqcS8IVO_el22OlnMZxSphewtZCPDHyjN87AyOM_c1CGdxWOrtOTbb5f645WjFOYO00HRb6EAXk-ctFwtFdV7U5YXoLj-Bu2SoThTjk&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;815&quot; data-original-width=&quot;1000&quot; height=&quot;523&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiKONn2eGMehvA4CkbVPbvEOvvfKcN93yvObODdRKzcrpvL8A_W--Z131OaXLBYqDWST37GlAht5YfiW3W6pS8ctqcS8IVO_el22OlnMZxSphewtZCPDHyjN87AyOM_c1CGdxWOrtOTbb5f645WjFOYO00HRb6EAXk-ctFwtFdV7U5YXoLj-Bu2SoThTjk=w640-h523&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjICaGAWghimtwrtdRuyjd4UVAvzCbja-zGou9nfEKQb-lBjrZ7NNBY-3hGr47qnd0crjm36xklVhClP2OsoHxfx5qjT9ygBko09jSjWXOiFD6tpei-Im3un6iNwZQiAc0f5HAeYOcvEPfsQkC1ORFT3hSY02UFcuy5sIfRFeJGvJZzl6TLO4plAOw8P5Y&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;818&quot; data-original-width=&quot;1003&quot; height=&quot;522&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjICaGAWghimtwrtdRuyjd4UVAvzCbja-zGou9nfEKQb-lBjrZ7NNBY-3hGr47qnd0crjm36xklVhClP2OsoHxfx5qjT9ygBko09jSjWXOiFD6tpei-Im3un6iNwZQiAc0f5HAeYOcvEPfsQkC1ORFT3hSY02UFcuy5sIfRFeJGvJZzl6TLO4plAOw8P5Y=w640-h522&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; id=&quot;architecture&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Architecture&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;22&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The backend is FastAPI with a deliberately boring service/repository split.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;24&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Routes handle HTTP only. Services coordinate profile management, audio processing, generation jobs, runtime diagnostics, and TTS orchestration. Repositories isolate SQLite persistence. Audio utilities handle normalization and metadata probing through FFmpeg and FFprobe.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The TTS runtime sits behind a&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;TtsEngine&lt;/code&gt;&amp;nbsp;interface. The generation service does not care whether the active engine is XTTS or Qwen3. It prepares a profile, builds a synthesis payload, writes the output to&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;data/generated&lt;/code&gt;, and records status updates in SQLite.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Synthesis runs as an in-process background job. That is enough for a local desktop-style app and avoids adding Redis, Celery, or other distributed infrastructure too early.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The frontend is React, TypeScript, Vite, React Router, and TanStack Query. The UI is desktop-first, dark, and intentionally simple: left navigation, profile cards, reference clip panels, a generation workspace, history, and diagnostics.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; id=&quot;the-xtts-lesson&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The XTTS Lesson&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The first implementation used Coqui XTTS v2.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;XTTS was a useful baseline because it can do zero-shot voice cloning from reference audio and it is relatively well-known in local TTS experiments. The app normalized clips, cached conditioning artifacts when possible, and used the selected primary clip as the conditioning source.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;But in practice, the output did not sound close enough. The voice often drifted into a generic speaker. In one test, the result sounded like a random English man rather than the target voice.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That was an important product lesson: a working local model integration is not the same thing as a good cloning experience.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The app was technically generating speech, but the speaker identity was not good enough.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; id=&quot;why-transcript-aware-cloning-helped&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why Transcript-Aware Cloning Helped&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;46&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The breakthrough was moving from audio-only cloning to transcript-aware cloning.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;48&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Qwen3-TTS expects the reference audio and the exact text spoken in that reference audio. That small workflow change matters. Instead of asking the model to infer everything from the waveform alone, the app gives it aligned acoustic and linguistic context.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;So the profile workflow changed:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Record or upload a clean reference clip.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;53&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Mark the best clip as primary.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Save the exact transcript of that clip.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Generate using Qwen3-TTS.&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;57&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The app now stores&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;reference_text&lt;/code&gt;&amp;nbsp;on each clip. The primary clip transcript becomes part of the conditioning fingerprint, so changing the transcript invalidates old cached prompts. There is also an optional local transcription path using a Whisper-style local ASR dependency, but manual transcript entry is always available and often better if the user knows exactly what they said.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This made the system feel much closer to the Voicebox-style workflow that worked well in practice.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;61&quot; dir=&quot;auto&quot; id=&quot;ux-details-that-matter&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;UX Details That Matter&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;63&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Local AI workflows often have long, silent waits. That is bad UX.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The app now shows loading feedback where it matters:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;Transcribe locally&lt;/code&gt;&amp;nbsp;button shows a spinner while transcription is running.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;68&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The transcription button is disabled while the action is in progress, preventing accidental duplicate requests.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;69&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;Generate audio&lt;/code&gt;&amp;nbsp;button shows a spinner while the job is starting or running.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;70&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The generate page warns if the selected primary clip is missing its transcript.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;72&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;These are small details, but they make the app feel more trustworthy. When local models take time to load, users need visible progress.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;74&quot; dir=&quot;auto&quot; id=&quot;running-it-locally&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Running It Locally&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;76&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The recommended path is Qwen3-TTS.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;78&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;From the repository root:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;80&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;powershell &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-ExecutionPolicy&lt;/span&gt; Bypass &lt;span class=&quot;hljs-operator&quot;&gt;-File&lt;/span&gt; .\scripts\setup.ps1
&amp;amp; .\.venv\Scripts\python.exe &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-m&lt;/span&gt; pip install &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;.\backend[qwen,transcription]&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;85&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Start the backend:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;87&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-variable&quot; style=&quot;color: #bd63c5;&quot;&gt;$env:LVS_TTS_ENGINE&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;qwen3&quot;&lt;/span&gt;
powershell &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-ExecutionPolicy&lt;/span&gt; Bypass &lt;span class=&quot;hljs-operator&quot;&gt;-File&lt;/span&gt; .\scripts\dev&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-backend&lt;/span&gt;.ps1
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Start the frontend:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;94&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;powershell &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-ExecutionPolicy&lt;/span&gt; Bypass &lt;span class=&quot;hljs-operator&quot;&gt;-File&lt;/span&gt; .\scripts\dev&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-frontend&lt;/span&gt;.ps1
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;98&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Then open:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;100&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;http://localhost:5173
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;104&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If another local app is already using port&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;8000&lt;/code&gt;, run the backend on&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;8010&lt;/code&gt;&amp;nbsp;and point the frontend proxy at it:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;106&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-variable&quot; style=&quot;color: #bd63c5;&quot;&gt;$env:LVS_TTS_ENGINE&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;qwen3&quot;&lt;/span&gt;
&lt;span class=&quot;hljs-variable&quot; style=&quot;color: #bd63c5;&quot;&gt;$env:LVS_BACKEND_PORT&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;8010&quot;&lt;/span&gt;
powershell &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-ExecutionPolicy&lt;/span&gt; Bypass &lt;span class=&quot;hljs-operator&quot;&gt;-File&lt;/span&gt; .\scripts\dev&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-backend&lt;/span&gt;.ps1
&lt;/code&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; color: #d4d4d4; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; white-space: pre-wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;112&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-variable&quot; style=&quot;color: #bd63c5;&quot;&gt;$env:VITE_API_TARGET&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot; style=&quot;color: #d69d85;&quot;&gt;&quot;http://127.0.0.1:8010&quot;&lt;/span&gt;
powershell &lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-ExecutionPolicy&lt;/span&gt; Bypass &lt;span class=&quot;hljs-operator&quot;&gt;-File&lt;/span&gt; .\scripts\dev&lt;span class=&quot;hljs-literal&quot; style=&quot;color: #569cd6;&quot;&gt;-frontend&lt;/span&gt;.ps1
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot; id=&quot;what-i-would-improve-next&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What I Would Improve Next&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The next improvements are mostly product polish and runtime hardening.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;121&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The app should make the active engine more visible in the main UI. Profiles should get a clear &quot;Qwen-ready&quot; badge when their primary clip has a transcript. The transcription workflow could show progress beyond a spinner, especially on first model load. The settings page could provide stronger guidance when the environment is missing Qwen, Whisper, CUDA, FFmpeg, or model weights.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;123&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Long-form generation also needs more work. The app currently supports normal generation jobs, but paragraph-aware chunking, concatenation, and better history grouping would make it more useful for narration.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;125&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Finally, Qwen and XTTS have different Python/runtime expectations. A future version could support separate engine environments or a small process boundary so users do not have to fit every model into one Python virtual environment.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;127&quot; dir=&quot;auto&quot; id=&quot;takeaway&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Takeaway&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The biggest lesson was that local-first voice cloning is not just about wiring up a model.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;131&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The workflow matters.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;For this project, XTTS proved the architecture and local storage model. Qwen3-TTS made the voice identity closer by adding the missing reference transcript. The resulting app is still early, but it now has the shape of a real local voice studio: profiles, clips, transcripts, generation history, runtime diagnostics, and no cloud dependency.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/04/building-local-voice-cloning-studio.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEg4rV9Sh3XmT5Cvdese1wY7GATOy0mXbzga6pP7WIXMfOrCILNT5jUWw1neCTsTqzpm_aGMJaOLX991wla6VmZtRu3UOcl_ri2h-7blx245iQxymuazIIpQARp0ymLuAytf5jUoCnlKw-kJ6gTxvLhUX-dfwdcozVJDW8YC6QosFyhd9DZczeKTniQNcNQ=s72-w320-h320-c" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-5149034108934542377</guid><pubDate>Mon, 13 Apr 2026 20:13:00 +0000</pubDate><atom:updated>2026-04-13T20:13:54.082+00:00</atom:updated><title>Beyond Prompts: Building a Codex Playbook for Real Application Development</title><description>&lt;p&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAUiFHHutCTN7kbhV5NxEhy5RFrz2jPL7g6veYGIeZYMYmmAuJFD5CN2JDSPWTJoFEqw7AtEl2Dz0NcfPdLbDWs8WUqg8wDyhbOXG0GlswtXRqbovFPIP7NtpJ2-Hm_AciRP7hosEvG5tm-J0b_VDi-XQhoIMzfmW7OzA7dHUu3peBWYFlepLPms-LbZY/s1536/ChatGPT%20Image%20Apr%2013,%202026,%2009_11_54%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAUiFHHutCTN7kbhV5NxEhy5RFrz2jPL7g6veYGIeZYMYmmAuJFD5CN2JDSPWTJoFEqw7AtEl2Dz0NcfPdLbDWs8WUqg8wDyhbOXG0GlswtXRqbovFPIP7NtpJ2-Hm_AciRP7hosEvG5tm-J0b_VDi-XQhoIMzfmW7OzA7dHUu3peBWYFlepLPms-LbZY/s320/ChatGPT%20Image%20Apr%2013,%202026,%2009_11_54%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;One-off prompting is weak engineering infrastructure.&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It can be useful for getting unstuck, drafting code, or exploring ideas, but it does not produce repeatable engineering behavior on its own. The same prompt that works acceptably on one backend feature often degrades into generic advice or inconsistent implementation on the next one. That happens because a prompt is usually trying to do too many jobs at once: repository policy, architectural philosophy, feature workflow, review heuristics, and implementation detail.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This repository was built to separate those concerns and make them durable.&amp;nbsp;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;a href=&quot;https://github.com/JordiCorbilla/codex-engineering-playbook&quot;&gt;JordiCorbilla/codex-engineering-playbook&lt;/a&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; id=&quot;the-core-problem&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Core Problem&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Most teams experimenting with coding agents start with giant instruction blobs. They pour style preferences, architecture opinions, code review heuristics, framework conventions, and edge-case warnings into a single file or prompt. That usually fails in predictable ways:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;durable guidance gets buried under temporary workflow detail&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;13&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the instructions become too large to scan and too vague to route reliably&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;project structure becomes secondary to the agent&#39;s last prompt&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;15&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;implementation becomes inconsistent across languages and application layers&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The problem is not that the model needs more words. The problem is that the repository needs a better operating model.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;19&quot; dir=&quot;auto&quot; id=&quot;what-this-repository-builds-instead&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What This Repository Builds Instead&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;21&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This playbook uses four layers:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;AGENTS.md&lt;/code&gt;&amp;nbsp;for durable repository-wide rules&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;24&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.agents/skills&lt;/code&gt;&amp;nbsp;for reusable workflows&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;templates&lt;/code&gt;&amp;nbsp;and&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;scripts&lt;/code&gt;&amp;nbsp;for deterministic implementation support&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;examples&lt;/code&gt;&amp;nbsp;for concrete, inspectable reference projects&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That split is the point of the repository.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The top-level&amp;nbsp;&lt;a data-href=&quot;../AGENTS.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/AGENTS.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;AGENTS.md&lt;/a&gt;&amp;nbsp;stays small. It says what the repository is for, when to prefer skills, what &quot;done&quot; means, and what kinds of validation are expected. It does not try to teach every implementation pattern directly. That restraint is important. Durable instructions should be hard to invalidate.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The detailed workflow logic moves into focused skills such as:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../.agents/skills/csharp-backend-feature/SKILL.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/.agents/skills/csharp-backend-feature/SKILL.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;csharp-backend-feature&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;35&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../.agents/skills/python-backend-review/SKILL.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/.agents/skills/python-backend-review/SKILL.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;python-backend-review&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../.agents/skills/react-typescript-feature/SKILL.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/.agents/skills/react-typescript-feature/SKILL.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;react-typescript-feature&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;37&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../.agents/skills/api-contract-review/SKILL.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/.agents/skills/api-contract-review/SKILL.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;api-contract-review&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../.agents/skills/layered-architecture-recon/SKILL.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/.agents/skills/layered-architecture-recon/SKILL.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;layered-architecture-recon&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This is better than a giant style blob because routing matters. Reviewing a Python backend diff is not the same task as implementing a React feature or mapping an unfamiliar layered architecture. Putting those workflows into separate skills makes the instructions sharper and more reusable.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot; id=&quot;why-durable-repo-instructions-matter&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why Durable Repo Instructions Matter&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Agent behavior improves when the repository teaches stable defaults instead of relying on the operator to restate them every time.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;46&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;In this repository, the durable defaults are simple:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;48&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;48&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;inspect existing structure first&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;49&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;keep boundaries clear&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;put logic in the right layer&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;51&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;validate the touched area before calling the work done&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;explain trade-offs when architecture changes&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Those rules are broad enough to matter across C#, Python, and React, but narrow enough to remain useful. They establish an operating model without pretending the languages are interchangeable.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot; id=&quot;why-skills-beat-giant-prompt-files&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why Skills Beat Giant Prompt Files&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;58&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;A single giant prompt tends to flatten all engineering work into &quot;follow best practices.&quot; That is almost always too soft. Real engineering work has modes, and the quality bar changes with the mode.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;60&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Feature work needs placement discipline. Review work needs risk detection. Contract review needs attention to caller-visible behavior. Architecture reconnaissance needs an accurate map, not rewrite advice.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;62&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is why the skills in this repository are intentionally separate:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;64&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;64&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;csharp-backend-feature&lt;/code&gt;&amp;nbsp;cares about thin controllers, service-led behavior, async correctness, DTO boundaries, and targeted tests.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;csharp-backend-review&lt;/code&gt;&amp;nbsp;cares about fat controllers, sync-over-async mistakes, leaky entity boundaries, and weak exception flows.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;66&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;python-backend-feature&lt;/code&gt;&amp;nbsp;emphasizes typed boundaries, thin request handling, explicit services, and restrained abstraction.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;frontend-ux-polish&lt;/code&gt;&amp;nbsp;is about hierarchy, spacing, labels, state clarity, and affordances, not broad frontend architecture.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;69&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Separating those workflows does two things. It makes routing more reliable, and it avoids making every task carry the weight of every other task&#39;s instructions.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;71&quot; dir=&quot;auto&quot; id=&quot;the-c-guidance&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The C# Guidance&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;73&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The C# portion of the playbook favors a layered ASP.NET Core style, but it is not blindly enterprise. The guidance in&amp;nbsp;&lt;a data-href=&quot;../conventions/csharp.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/conventions/csharp.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;conventions/csharp.md&lt;/a&gt;&amp;nbsp;pushes toward controllers, services, and repositories when those boundaries provide real value. It also says something many style guides avoid saying clearly: repository abstractions can become ceremony.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;75&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That trade-off matters. In the&amp;nbsp;&lt;a data-href=&quot;../examples/csharp-api&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/csharp-api&quot; style=&quot;text-decoration-line: none;&quot;&gt;C# example app&lt;/a&gt;, the repository boundary exists because it helps keep persistence concerns separate and makes the service easy to test. But it stays intentionally small and in-memory. The goal is to demonstrate responsibility boundaries and async flow, not to perform ORM theater.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;77&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The example includes:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;79&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;79&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/csharp-api/src/CodexEngineeringPlaybook.CSharpApi/Controllers/OrdersController.cs&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/csharp-api/src/CodexEngineeringPlaybook.CSharpApi/Controllers/OrdersController.cs&quot; style=&quot;text-decoration-line: none;&quot;&gt;OrdersController.cs&lt;/a&gt;&amp;nbsp;for HTTP concerns&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;80&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/csharp-api/src/CodexEngineeringPlaybook.CSharpApi/Services/OrderService.cs&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/csharp-api/src/CodexEngineeringPlaybook.CSharpApi/Services/OrderService.cs&quot; style=&quot;text-decoration-line: none;&quot;&gt;OrderService.cs&lt;/a&gt;&amp;nbsp;for validation, orchestration, and business flow&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;81&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/csharp-api/src/CodexEngineeringPlaybook.CSharpApi/Repositories/InMemoryOrderRepository.cs&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/csharp-api/src/CodexEngineeringPlaybook.CSharpApi/Repositories/InMemoryOrderRepository.cs&quot; style=&quot;text-decoration-line: none;&quot;&gt;InMemoryOrderRepository.cs&lt;/a&gt;&amp;nbsp;for isolated storage behavior&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;82&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/csharp-api/src/CodexEngineeringPlaybook.CSharpApi/Middleware/ExceptionMappingMiddleware.cs&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/csharp-api/src/CodexEngineeringPlaybook.CSharpApi/Middleware/ExceptionMappingMiddleware.cs&quot; style=&quot;text-decoration-line: none;&quot;&gt;ExceptionMappingMiddleware.cs&lt;/a&gt;&amp;nbsp;for centralized error translation&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;84&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is a good example of the repository&#39;s overall stance: use structure to clarify responsibilities, not to multiply files for their own sake.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;86&quot; dir=&quot;auto&quot; id=&quot;the-python-guidance&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Python Guidance&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;88&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Python code often swings between two bad extremes when teams talk about architecture. One extreme is route handlers full of business logic and IO. The other is an imported enterprise pattern that creates classes, abstract base types, and indirection that the codebase has not earned.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;90&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The Python guidance in&amp;nbsp;&lt;a data-href=&quot;../conventions/python.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/conventions/python.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;conventions/python.md&lt;/a&gt;&amp;nbsp;tries to avoid both.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It emphasizes:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;94&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;94&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;thin request handling&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;95&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;typed boundaries&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;explicit validation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;97&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;clear service or module ownership&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;98&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;simplicity over cleverness&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;100&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;In the&amp;nbsp;&lt;a data-href=&quot;../examples/python-api&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/python-api&quot; style=&quot;text-decoration-line: none;&quot;&gt;Python example app&lt;/a&gt;, the route module translates HTTP concerns, the service owns the business path, and the data-access layer stores records in memory. The example is intentionally small, but the boundaries are inspectable:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;102&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;102&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/python-api/app/routes/orders.py&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/python-api/app/routes/orders.py&quot; style=&quot;text-decoration-line: none;&quot;&gt;orders.py&lt;/a&gt;&amp;nbsp;keeps request handling thin&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;103&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/python-api/app/services/orders.py&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/python-api/app/services/orders.py&quot; style=&quot;text-decoration-line: none;&quot;&gt;orders.py&lt;/a&gt;&amp;nbsp;owns the business behavior&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;104&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/python-api/app/data/orders.py&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/python-api/app/data/orders.py&quot; style=&quot;text-decoration-line: none;&quot;&gt;orders.py&lt;/a&gt;&amp;nbsp;isolates storage concerns&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;105&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/python-api/app/schemas/orders.py&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/python-api/app/schemas/orders.py&quot; style=&quot;text-decoration-line: none;&quot;&gt;orders.py&lt;/a&gt;&amp;nbsp;defines typed request and response models&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;107&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That structure is useful because it makes future changes cheaper. A new validation rule or storage implementation has an obvious home.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;109&quot; dir=&quot;auto&quot; id=&quot;the-react--typescript-guidance&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The React + TypeScript Guidance&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;111&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Frontend guidance is often too aesthetic or too abstract. This playbook is trying to be engineering guidance, so the React conventions focus on code structure, state handling, and contract discipline.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;113&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The priorities in&amp;nbsp;&lt;a data-href=&quot;../conventions/react-typescript.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/conventions/react-typescript.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;conventions/react-typescript.md&lt;/a&gt;&amp;nbsp;are:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;keep components focused&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;116&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;separate API access from rendering&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;make loading, error, and empty states explicit&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;118&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;type props and async data honestly&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;keep hooks disciplined&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;120&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;avoid business logic hidden in JSX&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;122&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The&amp;nbsp;&lt;a data-href=&quot;../examples/react-app&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/react-app&quot; style=&quot;text-decoration-line: none;&quot;&gt;React example app&lt;/a&gt;&amp;nbsp;is not a design system demo. It is a small application slice showing the separation between transport, state, and presentation:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;124&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;124&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/react-app/src/api/orders.ts&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/react-app/src/api/orders.ts&quot; style=&quot;text-decoration-line: none;&quot;&gt;orders.ts&lt;/a&gt;&amp;nbsp;owns data access behavior&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;125&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/react-app/src/hooks/useOrders.ts&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/react-app/src/hooks/useOrders.ts&quot; style=&quot;text-decoration-line: none;&quot;&gt;useOrders.ts&lt;/a&gt;&amp;nbsp;models async state transitions&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;126&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/react-app/src/components/OrderSummaryList.tsx&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/react-app/src/components/OrderSummaryList.tsx&quot; style=&quot;text-decoration-line: none;&quot;&gt;OrderSummaryList.tsx&lt;/a&gt;&amp;nbsp;renders typed data&lt;/span&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;127&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;a data-href=&quot;../examples/react-app/src/App.tsx&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/examples/react-app/src/App.tsx&quot; style=&quot;text-decoration-line: none;&quot;&gt;App.tsx&lt;/a&gt;&amp;nbsp;composes the UI and makes loading, empty, and error states visible&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is deliberate. Many generated React examples hide the interesting part of the problem inside a single file. This one does not.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;131&quot; dir=&quot;auto&quot; id=&quot;why-the-examples-matter&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why The Examples Matter&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Example apps are not filler in a repository like this. They are operational anchors.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Without examples, convention documents drift toward abstract advice. Skills become more likely to overfit to generic framework knowledge. Templates become harder to evaluate because there is no concrete reference point for what &quot;good&quot; looks like in the repository.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;137&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The examples in this playbook make the guidance testable. They show the relationship between the documents and actual code. They also give Codex stable insertion points when exploring an unfamiliar but similarly structured codebase.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;139&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The practical run instructions live in the repository&amp;nbsp;&lt;a data-href=&quot;../README.md&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/README.md&quot; style=&quot;text-decoration-line: none;&quot;&gt;README&lt;/a&gt;. That split is intentional: the blog explains the design, while the README acts as the operational starting point.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;141&quot; dir=&quot;auto&quot; id=&quot;scripts-and-templates-as-engineering-tools&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Scripts And Templates As Engineering Tools&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Another failure mode in agent-oriented repositories is over-explaining deterministic work in prose. If a C# controller shape is predictable, a template is better than another paragraph. If you need to discover likely insertion points or summarize changed files, a small script is usually better than asking the model to infer everything from scratch every time.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;145&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is why this repository includes:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;147&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;147&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../templates/csharp&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/templates/csharp&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;templates/csharp&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;148&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../templates/python&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/templates/python&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;templates/python&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;149&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../templates/react&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/templates/react&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;templates/react&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;150&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../scripts/scan_repo.py&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/scripts/scan_repo.py&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;scripts/scan_repo.py&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;151&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../scripts/find_feature_insertion_points.py&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/scripts/find_feature_insertion_points.py&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;scripts/find_feature_insertion_points.py&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;152&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../scripts/discover_tests.py&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/scripts/discover_tests.py&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;scripts/discover_tests.py&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;153&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../scripts/summarize_changed_files.py&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/scripts/summarize_changed_files.py&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;scripts/summarize_changed_files.py&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;154&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;a data-href=&quot;../scripts/validate_playbook.py&quot; href=&quot;https://file+.vscode-resource.vscode-cdn.net/c%3A/repo/codex-engineering-playbook/scripts/validate_playbook.py&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: black;&quot;&gt;scripts/validate_playbook.py&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;156&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;These are small on purpose. They exist to support repeatability, not to introduce another platform inside the repository.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;158&quot; dir=&quot;auto&quot; id=&quot;strengths&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Strengths&lt;/h2&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;160&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;160&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The repository is structured for reuse, not just demonstration.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;161&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The top-level instructions are durable enough to survive ordinary growth.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The skills are narrow enough to route reliably.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;163&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The examples make the guidance concrete instead of rhetorical.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;164&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The validation bar is lightweight but real.&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;166&quot; dir=&quot;auto&quot; id=&quot;limitations&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Limitations&lt;/h2&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;168&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;168&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The playbook is intentionally opinionated, which means it will not fit every team culture.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;169&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The examples are small; they demonstrate boundaries, not the full complexity of production systems.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;170&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The repository does not solve framework-specific edge cases beyond the patterns it chooses to illustrate.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;171&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Skills can become stale if a team&#39;s real architecture evolves and the playbook does not.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;173&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;There is also a rigidity trade-off. If a team treats the playbook as law rather than guidance, it can become a local maximum. Not every codebase needs controller/service/repository layering. Not every React feature needs another hook. Not every Python service needs another module boundary. Good playbooks create defaults, not dogma.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;175&quot; dir=&quot;auto&quot; id=&quot;where-this-helps-most&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Where This Helps Most&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;177&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This approach helps most when:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;179&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;179&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a team wants more repeatable coding-agent behavior&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;180&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the codebase already values clear boundaries&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;181&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;multiple languages need a shared architectural vocabulary&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;182&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;implementation and review workflows should be routable and explicit&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;184&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It helps less when:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;186&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;186&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the codebase is intentionally experimental&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;187&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;architecture changes weekly&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;188&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;framework-specific constraints dominate general engineering structure&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;189&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the team wants maximal freedom and minimal convention&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;191&quot; dir=&quot;auto&quot; id=&quot;pros-and-cons&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Pros And Cons&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;193&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Pros:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;195&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;195&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;better repeatability than one-off prompts&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;196&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;clearer separation between policy, workflow, and implementation detail&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;197&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;easier extension through focused skills&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;198&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;stronger grounding through examples and validation&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;200&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Cons:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;202&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;202&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;more repository structure to maintain&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;203&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;more upfront design work than dropping a prompt file into a repo&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;204&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;some duplication between conventions, skills, and examples is intentional and needs upkeep&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;205&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;can become too rigid if teams stop exercising judgment&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;207&quot; dir=&quot;auto&quot; id=&quot;final-view&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Final View&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;209&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The point of this repository is not to prove that Codex can follow instructions. The point is to make those instructions worth following.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;211&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That requires durable repository guidance, focused workflow skills, deterministic helpers, and concrete examples. It also requires saying no to the usual temptation to dump everything into a single mega-prompt and hope the agent will sort it out.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;213&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That temptation is understandable. It is also a weak substitute for engineering structure.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/04/beyond-prompts-building-codex-playbook.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAUiFHHutCTN7kbhV5NxEhy5RFrz2jPL7g6veYGIeZYMYmmAuJFD5CN2JDSPWTJoFEqw7AtEl2Dz0NcfPdLbDWs8WUqg8wDyhbOXG0GlswtXRqbovFPIP7NtpJ2-Hm_AciRP7hosEvG5tm-J0b_VDi-XQhoIMzfmW7OzA7dHUu3peBWYFlepLPms-LbZY/s72-c/ChatGPT%20Image%20Apr%2013,%202026,%2009_11_54%20PM.png" height="72" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-1668364096065516364</guid><pubDate>Sun, 12 Apr 2026 18:27:00 +0000</pubDate><atom:updated>2026-04-12T18:27:03.863+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">codex</category><category domain="http://www.blogger.com/atom/ns#">layer</category><category domain="http://www.blogger.com/atom/ns#">openAI</category><category domain="http://www.blogger.com/atom/ns#">Skills</category><title>Skills for Codex: The missing layer between prompts and reliable workflows</title><description>&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU3qPmBKKpcVqtbbLGQfIJ7pDA1SupuZcJHIdA0tenFtSAFWJaHK1jQSBYh9i_-GKSBWNhfJuA0QVgxIfwe3HxYcnMxJy4h1WyPgyzFnjYa8DxQaGw3zgRq12HjD2q3FLWrzxGgHJbg9hDIo3j0AMv_OMjPHEgD9i7KLIk793NtcEx37dscUOdQ3x84Aw/s1536/ChatGPT%20Image%20Apr%2012,%202026,%2007_23_49%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU3qPmBKKpcVqtbbLGQfIJ7pDA1SupuZcJHIdA0tenFtSAFWJaHK1jQSBYh9i_-GKSBWNhfJuA0QVgxIfwe3HxYcnMxJy4h1WyPgyzFnjYa8DxQaGw3zgRq12HjD2q3FLWrzxGgHJbg9hDIo3j0AMv_OMjPHEgD9i7KLIk793NtcEx37dscUOdQ3x84Aw/s320/ChatGPT%20Image%20Apr%2012,%202026,%2007_23_49%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif;&quot;&gt;The real unlock for coding agents is packaging workflows into&amp;nbsp;&lt;/span&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;AGENTS.md&lt;/code&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif;&quot;&gt;, skills, and scripts&lt;/span&gt;&lt;/b&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Most teams experimenting with coding agents are still operating at the wrong layer.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;They keep trying to get reliability by writing better prompts. That helps a little. It does not solve the real problem.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The hard part is not telling the model to &quot;be careful&quot; or &quot;think step by step.&quot; The hard part is turning repeated engineering workflows into artifacts the agent can reuse: repo instructions, narrowly scoped skills, and deterministic helper scripts.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is what I built in this demo repository.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The repo is small on purpose. It contains a tiny legacy-style Python service, four concrete Codex skills, a short&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;AGENTS.md&lt;/code&gt;, several Python scripts, and lightweight tests. The point is not to show off a toy prompt library. The point is to show what a serious workflow layer looks like when you want an agent to behave more like an engineer and less like an improv partner.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;One-line takeaway:&amp;nbsp;&lt;strong&gt;prompting is too ephemeral for repeated engineering work.&lt;/strong&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Another one:&amp;nbsp;&lt;strong&gt;if a workflow matters more than once, it should probably exist as a repo artifact.&lt;/strong&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; id=&quot;why-prompting-alone-breaks-down&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why prompting alone breaks down&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;One-off prompting degrades for boring reasons:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;22&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;22&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The same task gets described slightly differently every time.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The agent re-derives the workflow from scratch.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;24&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Deterministic steps get handled as prose instead of code.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The model mixes operational guidance with local reasoning and drops part of it under pressure.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Senior engineers already know this pattern from human systems. If a workflow matters, we do not rely on memory alone. We add runbooks, scripts, templates, checks, and conventions.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;29&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Coding agents need the same thing.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;31&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&quot;Please inspect the code carefully before changing anything&quot; is not a reliable mechanism. It is a wish. A skill with explicit triggers, steps, outputs, and boundaries is a mechanism.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;33&quot; dir=&quot;auto&quot; id=&quot;the-missing-layer-agentsmd--skills--scripts&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The missing layer:&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;AGENTS.md&lt;/code&gt;&amp;nbsp;+ skills + scripts&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;35&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The repo uses three layers, each doing a different job.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;37&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;AGENTS.md&lt;/code&gt;&amp;nbsp;is the repo-level contract. It tells Codex how work should be done here:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;prefer skills for recurring workflows&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;39&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;use scripts for deterministic tasks&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;validate changes before calling them done&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;41&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;plan first when risk or ambiguity is non-trivial&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;43&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That file is intentionally short. Repo instructions are more useful when they set constraints and decision rules, not when they try to micromanage every possible action.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;45&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The skills are the workflow layer. Each one has a sharp name, obvious routing description, trigger conditions, workflow steps, expected outputs, and boundaries. That matters because routing quality is part of the problem. If skill names are vague, the agent will miss them or apply them at the wrong time.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;47&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The scripts are there for the parts that should not depend on language generation at all. Parsing test failures, scanning a repo for hotspots, and extracting risk signals from a diff are all better handled with code than with a paragraph of instructions.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;49&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;One-line takeaway:&amp;nbsp;&lt;strong&gt;natural language is a poor substitute for a parser.&lt;/strong&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;51&quot; dir=&quot;auto&quot; id=&quot;the-example-repo&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The example repo&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;53&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The demo repo has a compact but realistic structure:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;skills/&lt;/code&gt;&amp;nbsp;contains four engineering workflows&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;scripts/&lt;/code&gt;&amp;nbsp;contains Python helpers for deterministic scanning and summarization&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;57&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;demo/legacy_service/&lt;/code&gt;&amp;nbsp;contains a deliberately awkward Python service&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;58&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;demo/artifacts/&lt;/code&gt;&amp;nbsp;contains failing test output and a risky sample diff&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;tests/&lt;/code&gt;&amp;nbsp;validates the scripts&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;61&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The service is small, but it has the right kind of mess:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;63&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;63&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;module-level in-memory storage&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;64&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a module-level cache&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;configuration read from environment at import time&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;66&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;time-sensitive pricing logic&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;hidden coupling between service, storage, and cache code&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;69&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is enough to make the skills meaningful. The repo is not pretending that agents only work on greenfield, well-factored code.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;71&quot; dir=&quot;auto&quot; id=&quot;how-to-get-the-repo-and-run-it&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;How to get the repo and run it&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;73&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The repository is here:&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;75&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;https://github.com/JordiCorbilla/engineering-skills-for-codex&lt;/code&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;77&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you want the full example locally, clone it and run the lightweight validation:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;79&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;git &lt;span class=&quot;hljs-built_in&quot;&gt;clone&lt;/span&gt; https://github.com/JordiCorbilla/engineering-skills-for-codex.git
&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt; engineering-skills-for-codex
python -m unittest discover -s tests -p &lt;span class=&quot;hljs-string&quot;&gt;&quot;test_*.py&quot;&lt;/span&gt; -v
python -m unittest discover -s demo/tests -p &lt;span class=&quot;hljs-string&quot;&gt;&quot;test_*.py&quot;&lt;/span&gt; -v
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;86&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;make&lt;/code&gt;&amp;nbsp;is available in your environment, the equivalent entry points are simpler:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;88&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;make &lt;span class=&quot;hljs-built_in&quot;&gt;test&lt;/span&gt;
make validate
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;93&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The skills themselves live under&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;skills/&lt;/code&gt;. In practice, you use them by opening the repo in Codex and invoking the workflow by name when the task matches. For example:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;95&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;95&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;ask Codex to use&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;investigate-before-patching&lt;/code&gt;&amp;nbsp;before editing&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;demo/legacy_service/services/order_service.py&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;ask Codex to use&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;summarize-test-failures&lt;/code&gt;&amp;nbsp;against&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;demo/artifacts/pytest_failure_output.txt&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;97&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;ask Codex to use&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;legacy-codebase-recon&lt;/code&gt;&amp;nbsp;on&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;demo/legacy_service&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;98&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;ask Codex to use&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;review-change-safely&lt;/code&gt;&amp;nbsp;on&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;demo/artifacts/sample_change.diff&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;100&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The deterministic parts can also be run directly without the skill wrapper:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;102&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;python scripts/inspect_patch_context.py --root demo --target demo/legacy_service/services/order_service.py
python scripts/summarize_test_failures.py --input demo/artifacts/pytest_failure_output.txt
python scripts/legacy_recon.py --root demo/legacy_service
python scripts/diff_review_summary.py --input demo/artifacts/sample_change.diff
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;109&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you want to reuse the skills in another repository, the practical starting point is to copy the relevant folder from&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;skills/&lt;/code&gt;, bring over any supporting script from&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;scripts/&lt;/code&gt;, and adapt&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;AGENTS.md&lt;/code&gt;&amp;nbsp;so the repo-level instructions match the codebase you actually have. Treat these skills as templates for repeatable workflows, not drop-in magic.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;111&quot; dir=&quot;auto&quot; id=&quot;the-skills&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The skills&lt;/h2&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;113&quot; dir=&quot;auto&quot; id=&quot;investigate-before-patching&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;investigate-before-patching&lt;/code&gt;&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This skill exists to stop speculative editing.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Before changing code, the workflow inspects the target module, local dependencies, related tests, and obvious coverage gaps. The helper script,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;scripts/inspect_patch_context.py&lt;/code&gt;, gives a deterministic first pass over imports, sibling modules, and nearby tests.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That sounds basic. It is also exactly the sort of discipline agents tend to skip when left alone. They jump to the patch because producing a patch is easier than earning one.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;121&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The important design choice here is scope. The skill does not promise a full call graph. It explicitly says the scan is a starting point and that critical modules still need to be read.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;123&quot; dir=&quot;auto&quot; id=&quot;summarize-test-failures&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;summarize-test-failures&lt;/code&gt;&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;125&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This skill handles a very common failure mode in agent-driven work: drowning in raw test output.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;127&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The script ingests a test log, extracts parseable failures, clusters them by likely cause, and produces a debugging brief. In the demo, the sample pytest log gets reduced to three concrete buckets:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;stale state or cache invalidation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;130&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;pricing rule regression&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;131&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;configuration drift&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is already more useful than dumping forty lines of traceback back at the user.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The limit is important though: this is a triage tool, not a diagnosis engine. If the log is messy or incomplete, the summary should stay humble.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;137&quot; dir=&quot;auto&quot; id=&quot;legacy-codebase-recon&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;legacy-codebase-recon&lt;/code&gt;&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;139&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This is the first-pass orientation skill for inherited systems.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;141&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The script looks for entry points and scores modules for hotspots using simple heuristics: mutable globals, environment coupling, cache usage, time-sensitive behavior, and general structural weight. On the demo service, it correctly flags the order service and repository layer as the riskiest modules.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This is exactly where skills can help: not by pretending to understand a legacy system instantly, but by providing a disciplined first pass that makes the next manual inspection smarter.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;145&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The failure mode is also obvious. Heuristics are directional. A hotspot score is not architecture truth.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;147&quot; dir=&quot;auto&quot; id=&quot;review-change-safely&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;review-change-safely&lt;/code&gt;&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;149&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This skill is designed for reviewing diffs with an emphasis on unintended side effects.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;151&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The demo diff changes a function signature, alters the returned payload shape, and replaces a guarded key lookup with a required-key lookup. The script surfaces all three and also notes that no tests moved with the behavior change.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;153&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is a useful baseline because many agent reviews default to a glorified summary. Serious review work needs findings, not narration.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;155&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The skill therefore forces a review shape:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;156&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;156&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;findings first&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;157&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;severity and confidence&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;158&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;file references&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;159&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;residual risk&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;161&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That structure matters. It is much easier to trust and act on than a free-form paragraph about what changed.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;163&quot; dir=&quot;auto&quot; id=&quot;why-scripts-matter&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why scripts matter&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;165&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The scripts are not there because Python is exciting. They are there because some tasks are simply better when the machine is forced to be literal.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;167&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Three examples:&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;169&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;First, parsing failure lines. Asking a model to &quot;read this pytest output and summarize it&quot; works until the output is long, repetitive, or messy. A parser is cheap and stable.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;171&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Second, scanning code for risk signals. Telling the model to &quot;look for tight coupling and hidden state&quot; is too vague on its own. A script can make that scan explicit and repeatable, even if the results are only heuristic.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;173&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Third, diff review. Function signature changes, payload key changes, and test coverage gaps are not subtle concepts. They should be machine-detectable.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;175&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The right split is simple:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;176&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;176&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;use scripts for deterministic extraction&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;177&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;use skills for workflow logic&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;178&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;use the model for judgment, prioritization, and synthesis&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;180&quot; dir=&quot;auto&quot; id=&quot;what-worked-well&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What worked well&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;182&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The most useful part of the repo is the layering.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;184&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;AGENTS.md&lt;/code&gt;&amp;nbsp;gives the repo a stable operating model. The skills give recurring tasks structure and routing clarity. The scripts prevent a class of drift where every run invents a slightly different method. The tests keep the helpers from silently rotting.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;186&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The second useful part is restraint. The skills are short. They are not trying to encode every engineering principle. They are only trying to make a few repeated workflows reliable enough to be worth using.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;188&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;One-line takeaway:&amp;nbsp;&lt;strong&gt;a narrow skill you can trust is worth more than a broad skill you cannot.&lt;/strong&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;190&quot; dir=&quot;auto&quot; id=&quot;what-still-does-not-work-well&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What still does not work well&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;192&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Skills do not remove the need for real engineering judgment.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;194&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;They do not understand runtime behavior. They do not replace reading the code. They do not magically fix weak tests, misleading names, or missing context from the user. They also do not help much when the task is genuinely novel and there is no repeated workflow to package.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;196&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;There is also a maintenance cost. Once you create a skill, you own it. If the repo changes and the skill instructions or script behavior drift, you have created a false sense of reliability.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;198&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This is why I would be cautious about building fifty skills too early. Most teams should start with a handful of painful, recurring workflows and make those solid.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;200&quot; dir=&quot;auto&quot; id=&quot;when-i-would-use-this-in-production&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;When I would use this in production&lt;/h2&gt;&lt;p class=&quot;code-line code-active-line&quot; data-line=&quot;202&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I would use this pattern in production when:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;204&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;204&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the team is repeatedly using agents on the same codebase&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;205&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the work includes bug triage, reviews, legacy recon, or change planning&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;206&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;there is enough repetition to justify a workflow artifact&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;207&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the team cares more about consistency than about model theatrics&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;209&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I would not bother in a repo where agent use is rare, the workflows are highly bespoke, or the codebase is changing so quickly that skill maintenance would dominate the value.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;211&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The threshold is not &quot;do we use AI?&quot; The threshold is &quot;do we keep repeating the same engineering moves?&quot;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;213&quot; dir=&quot;auto&quot; id=&quot;closing-thoughts&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Closing thoughts&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;215&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The claim here is modest.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;217&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Coding agents do not become reliable because we found the perfect prompt. They become more useful when we stop forcing the model to reinvent stable workflows on every task.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;219&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That means packaging the workflow.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;221&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Write the repo contract in&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;AGENTS.md&lt;/code&gt;. Turn repeated tasks into skills with real boundaries. Move deterministic steps into scripts. Test those scripts. Then let the model operate inside that frame.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;223&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is less glamorous than prompt alchemy. It is also much closer to how engineering systems usually become dependable.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/04/skills-for-codex-missing-layer-between.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU3qPmBKKpcVqtbbLGQfIJ7pDA1SupuZcJHIdA0tenFtSAFWJaHK1jQSBYh9i_-GKSBWNhfJuA0QVgxIfwe3HxYcnMxJy4h1WyPgyzFnjYa8DxQaGw3zgRq12HjD2q3FLWrzxGgHJbg9hDIo3j0AMv_OMjPHEgD9i7KLIk793NtcEx37dscUOdQ3x84Aw/s72-c/ChatGPT%20Image%20Apr%2012,%202026,%2007_23_49%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-4287333928539196813</guid><pubDate>Wed, 08 Apr 2026 15:34:00 +0000</pubDate><atom:updated>2026-04-08T16:24:22.906+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">analysis</category><category domain="http://www.blogger.com/atom/ns#">correlation</category><category domain="http://www.blogger.com/atom/ns#">funds</category><category domain="http://www.blogger.com/atom/ns#">ISA</category><category domain="http://www.blogger.com/atom/ns#">overlap</category><category domain="http://www.blogger.com/atom/ns#">Vanguard</category><title>Building Fund Overlap Lab: From Surface Labels to Real Exposure</title><description>&lt;p&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-size: 14px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfpNBdLfrDBwJXjPDzuPwIJO95u87e6xBjljAmfbTeBI5Iv0nddYH4bK77Wm-Gh75bJkvRl3s7w-fNAKdBt4AtRi7K3d_pW9_rQB_LOXUT9VzXQqwtnUgKgeSEJJyuVpWmlsmZD7HCTnOva73Lu1OorvGuO_mEaZ1uBOguxBhKtqVFYEgu8Vj7ok8MmVk/s1536/ChatGPT%20Image%20Apr%208,%202026,%2004_31_56%20PM.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfpNBdLfrDBwJXjPDzuPwIJO95u87e6xBjljAmfbTeBI5Iv0nddYH4bK77Wm-Gh75bJkvRl3s7w-fNAKdBt4AtRi7K3d_pW9_rQB_LOXUT9VzXQqwtnUgKgeSEJJyuVpWmlsmZD7HCTnOva73Lu1OorvGuO_mEaZ1uBOguxBhKtqVFYEgu8Vj7ok8MmVk/s320/ChatGPT%20Image%20Apr%208,%202026,%2004_31_56%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;If you have ever compared two multi-asset funds and thought, &quot;These look different, but are they actually different?&quot; this project is for that exact problem.&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Fund Overlap Lab is a Python tool for &lt;b&gt;Vanguard UK funds&lt;/b&gt; that retrieves holdings, normalizes names, and calculates overlap. It includes a CLI for fast checks and a Streamlit app for interactive analysis.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;a href=&quot;https://github.com/JordiCorbilla/fund-overlap-lab&quot;&gt;JordiCorbilla/fund-overlap-lab: fund-overlap-lab&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line code-active-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; id=&quot;why-it-exists&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why It Exists&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Wrapper funds such as &lt;a href=&quot;https://www.vanguardinvestor.co.uk/what-we-offer/all-products&quot;&gt;LifeStrategy&lt;/a&gt; and Target Retirement can look distinct at the top level while sharing large portions of the same underlying exposures.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The project aims to make that visible by combining:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;look-through holdings&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;13&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;transparent overlap math&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;risk and cost context&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;15&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;practical UI workflows for real portfolio conversations&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, Segoe WPC, Segoe UI, system-ui, Ubuntu, Droid Sans, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, Segoe WPC, Segoe UI, system-ui, Ubuntu, Droid Sans, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 14px;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjLVa1iABN846Z7ZQZAp0avPjC7aco-0Px6x_KP9DHvtpWffaWIcZgBZMv7W0xmZXhueSOTt_HG4mQrtUbT3ChOAae0tEGEECfW18EIv4rSdSaBzZxD5k6F60NDjvrrJVOdLHC4VhvPME4yGm7bg-Yhrc7IF8hakWkPutDRRRNThPAythrk6ht-gGDurpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1472&quot; data-original-width=&quot;959&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjLVa1iABN846Z7ZQZAp0avPjC7aco-0Px6x_KP9DHvtpWffaWIcZgBZMv7W0xmZXhueSOTt_HG4mQrtUbT3ChOAae0tEGEECfW18EIv4rSdSaBzZxD5k6F60NDjvrrJVOdLHC4VhvPME4yGm7bg-Yhrc7IF8hakWkPutDRRRNThPAythrk6ht-gGDurpg=w416-h640&quot; width=&quot;416&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot; id=&quot;core-overlap-model&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Core Overlap Model&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;19&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;For two funds, overlap is calculated as:&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;21&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;sum(min(weight_a_i, weight_b_i))&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;where each i is a normalized underlying holding.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The app then reports:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;overlap percentage&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;shared and distinct holdings&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;29&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;only-in-A and only-in-B tables&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;bucket-level aggregation&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, Segoe WPC, Segoe UI, system-ui, Ubuntu, Droid Sans, sans-serif&quot;&gt;&lt;span style=&quot;font-size: 14px;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjW84xNrTrdn6PwRi4qENB-igpDEBW6XLUG3a14jpU2wTsG5if-7WMOiBBrCf2jzuDeMThPX3-KQnU7hI3hkrTTG__A4R-fl5icWnQ-E36DYBlZtASjxzKFOtgezRxdvkroJlllyqUuwEoAK0CGeUYn12wKuA3Bp2zoAFxLE_RskoBjPh1Apxl-cY8VQBU&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1232&quot; data-original-width=&quot;912&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjW84xNrTrdn6PwRi4qENB-igpDEBW6XLUG3a14jpU2wTsG5if-7WMOiBBrCf2jzuDeMThPX3-KQnU7hI3hkrTTG__A4R-fl5icWnQ-E36DYBlZtASjxzKFOtgezRxdvkroJlllyqUuwEoAK0CGeUYn12wKuA3Bp2zoAFxLE_RskoBjPh1Apxl-cY8VQBU=w475-h640&quot; width=&quot;475&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhv5GFGczcfJkVMxRVaebapKBbfbvC3T4FDg8M05LvzL-bvEYizs7SokWRaY0gSXfb_fszj87TREGiaVwAI8l-NQJZzdxHwRaR9-Q9dq1-aLWp-Ls0UYnFlkIc7pY4QE7JLvZEHDK6FugoNzdZIZge8q1LeCato1_w292XsSXTlxvkEP-PJoaLNaKUaPgk&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;958&quot; data-original-width=&quot;905&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhv5GFGczcfJkVMxRVaebapKBbfbvC3T4FDg8M05LvzL-bvEYizs7SokWRaY0gSXfb_fszj87TREGiaVwAI8l-NQJZzdxHwRaR9-Q9dq1-aLWp-Ls0UYnFlkIc7pY4QE7JLvZEHDK6FugoNzdZIZge8q1LeCato1_w292XsSXTlxvkEP-PJoaLNaKUaPgk=w605-h640&quot; width=&quot;605&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; id=&quot;data-pipeline-what-changed-and-why&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Data Pipeline: What Changed and Why&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Early versions parsed portfolio HTML tables. That broke when pages shifted to JS-driven rendering. The current pipeline is built to survive those changes.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Current strategy:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;primary source: GraphQL endpoint for detailed holdings&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;39&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;fallback source: HTML table/text extraction where possible&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;resilience fallback: API asset-allocation level extraction&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;41&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;dynamic product lookup from Vanguard product catalog&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;43&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This layered approach keeps the tool operational when upstream page structures move.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;45&quot; dir=&quot;auto&quot; id=&quot;how-data-access-works-technical&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;How Data Access Works&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;47&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Under the hood, the provider follows a staged resolution and retrieval flow:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;49&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;49&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Product resolution&lt;/li&gt;&lt;/ol&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;51&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;51&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the app accepts multiple identifiers (fund code, SEDOL, slug)&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;it queries Vanguard UK product metadata and resolves those inputs to canonical product fields (including portId)&lt;/li&gt;&lt;/ul&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; start=&quot;2&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Primary holdings retrieval (GraphQL)&lt;/li&gt;&lt;/ol&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;with the resolved product, it calls Vanguard UK GraphQL endpoints to fetch holdings details&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;57&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;this path returns richer data than static page scraping, including constituent-level rows where available&lt;/li&gt;&lt;/ul&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot; start=&quot;3&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Recursive expansion (optional)&lt;/li&gt;&lt;/ol&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;61&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;61&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;in Ultimate Look-Through mode, holdings that are themselves funds or ETFs can be expanded recursively&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;62&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;each child weight is multiplied through the parent path weight&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;63&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;recursion is bounded by max depth and protected against cycles&lt;/li&gt;&lt;/ul&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot; start=&quot;4&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Fallback retrieval&lt;/li&gt;&lt;/ol&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;if detailed holdings cannot be retrieved, the provider falls back to HTML extraction and then allocation-level API data&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;68&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;this keeps the app functional even when one upstream path changes&lt;/li&gt;&lt;/ul&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;70&quot; dir=&quot;auto&quot; start=&quot;5&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;70&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Normalization and comparison preparation&lt;/li&gt;&lt;/ol&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;72&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;72&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;holding names are normalized for robust joins&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;73&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;duplicate rows are consolidated&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;74&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;percentage fields are standardized before overlap calculations&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;76&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This design keeps the user workflow simple while handling real-world upstream variability in a resilient way.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;78&quot; dir=&quot;auto&quot; id=&quot;ultimate-look-through-mode-recursive&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Ultimate Look-Through Mode (Recursive)&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;80&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;A major upgrade is recursive decomposition of fund-of-funds structures.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;82&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;You can now choose between:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;84&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;84&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Direct Holdings mode: one layer of holdings&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;85&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Ultimate Look-Through mode: recursively expands eligible underlying funds and ETFs&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;87&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Both Two-Fund Compare and Portfolio Analysis now include:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;89&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;89&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;an Ultimate Look-Through toggle&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;90&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a max depth control to limit recursion&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;91&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;cycle protection so recursive expansion does not loop&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;93&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This matters for mixed wrappers where one level of holdings is still another basket.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;95&quot; dir=&quot;auto&quot; id=&quot;streamlit-ux-improvements&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Example Questions It Answers Quickly&lt;/h2&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;126&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;126&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;How much overlap exists between a LifeStrategy fund and a Target Retirement fund right now?&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;127&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Is a portfolio diversified across managers and wrappers, or concentrated in repeated underlyings?&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;128&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Do risk and OCF differences align with actual exposure differences?&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Does recursive look-through materially change the diversification story?&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;131&quot; dir=&quot;auto&quot; id=&quot;project-structure&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Project Structure&lt;/h2&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;fund_overlap_lab/providers.py: data access, product resolution, holdings retrieval&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;134&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;fund_overlap_lab/compare.py: overlap and portfolio analytics&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;fund_overlap_lab/models.py: data models&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;136&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;fund_overlap_lab/buckets.py: coarse asset bucketing&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;137&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;fund_overlap_lab/cli.py: command-line workflows&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;138&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;app.py: Streamlit experience&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;140&quot; dir=&quot;auto&quot; id=&quot;run-it&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Run It&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;142&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Install:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;144&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;150&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;CLI compare:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;152&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;python -m fund_overlap_lab.cli compare VGL100A VAR45GA
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;156&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Streamlit app:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;158&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;streamlit run app.py
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; id=&quot;what-is-next&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Final Thought&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;174&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Fund Overlap Lab is intentionally practical. It is built to help answer a real question before making allocation changes:&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;176&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;b&gt;&quot;Am I truly diversifying, or buying the same exposure through different wrappers?&quot;&lt;/b&gt;&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/04/building-fund-overlap-lab-from-surface.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfpNBdLfrDBwJXjPDzuPwIJO95u87e6xBjljAmfbTeBI5Iv0nddYH4bK77Wm-Gh75bJkvRl3s7w-fNAKdBt4AtRi7K3d_pW9_rQB_LOXUT9VzXQqwtnUgKgeSEJJyuVpWmlsmZD7HCTnOva73Lu1OorvGuO_mEaZ1uBOguxBhKtqVFYEgu8Vj7ok8MmVk/s72-c/ChatGPT%20Image%20Apr%208,%202026,%2004_31_56%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-3652035870410943406</guid><pubDate>Tue, 07 Apr 2026 09:43:00 +0000</pubDate><atom:updated>2026-04-07T09:43:39.530+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">instruments</category><category domain="http://www.blogger.com/atom/ns#">library</category><category domain="http://www.blogger.com/atom/ns#">quant developer</category><category domain="http://www.blogger.com/atom/ns#">reference library</category><title>Building a Quant Developer Reference Library</title><description>&lt;p&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbOhavBnCgK2-8XdJdGE0nYsZp8vtXe3usDHnH0MNWZLJO5pPRrjEyVw2nO-Dw7oVyTazsxY9D3NjuukB_QzbfovdZ0Wqwu7i1y0p3DB-H1vCpzvryf7bHXQJiWbI1-cHxQ1G5NbN-or6mfai3KgtGbk6SHZlAFnPnJcdH6c50sWCt_PqbfTFYo7zxwQE/s1536/ChatGPT%20Image%20Apr%207,%202026,%2010_38_15%20AM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbOhavBnCgK2-8XdJdGE0nYsZp8vtXe3usDHnH0MNWZLJO5pPRrjEyVw2nO-Dw7oVyTazsxY9D3NjuukB_QzbfovdZ0Wqwu7i1y0p3DB-H1vCpzvryf7bHXQJiWbI1-cHxQ1G5NbN-or6mfai3KgtGbk6SHZlAFnPnJcdH6c50sWCt_PqbfTFYo7zxwQE/s320/ChatGPT%20Image%20Apr%207,%202026,%2010_38_15%20AM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;For a long time, I wanted a single place that explained quantitative finance the way quant developers actually need it explained.&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Not as a pure math textbook. Not as a collection of interview flashcards. Not as a random pile of disconnected notes.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I wanted something practical. Something that connects pricing theory to implementation. Something that helps you move from &quot;I know the formula&quot; to &quot;I can build this correctly, test it, and trust it in production.&quot;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;So I started building the&amp;nbsp;&lt;strong&gt;Quantitative Developer Reference Library&lt;/strong&gt;.&amp;nbsp;&lt;a href=&quot;https://github.com/JordiCorbilla/Quantitative-Developer-Reference-Library&quot;&gt;JordiCorbilla/Quantitative-Developer-Reference-Library: Quantitative-Developer-Reference-Library&lt;/a&gt;&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; id=&quot;why-this-exists&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why This Exists&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;A lot of great quantitative finance material already exists. The problem is not the lack of information. The problem is fragmentation.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you are a quant developer, the knowledge you need is usually scattered across:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;textbooks that go deep on theory but say little about implementation,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;code samples that skip market conventions and edge cases,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;19&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;desk knowledge that lives in someone&#39;s head,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;internal wikis that are useful but never portable,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;21&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and years of trial and error that are expensive to repeat.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That leaves a gap between understanding the model and building the system.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;In practice, that gap is where most of the pain lives:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;curves built with the wrong conventions,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;volatility surfaces that look smooth but produce nonsense risk,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;pricing engines that work for the happy path but fail on real trades,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;29&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;PnL explain that does not reconcile,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;market data that is technically available but not analytically usable,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;31&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and analytics platforms that become hard to trust as they grow.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;33&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This repository is meant to close that gap.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;35&quot; dir=&quot;auto&quot; id=&quot;what-the-library-tries-to-do&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What The Library Tries To Do&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;37&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The goal is simple:&lt;/p&gt;&lt;blockquote class=&quot;code-line&quot; data-line=&quot;39&quot; dir=&quot;auto&quot; style=&quot;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(34, 34, 34); border-color: rgba(0, 122, 204, 0.5); border-left-style: solid; border-left-width: 5px; border-radius: 2px; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin: 0px; padding: 0px 16px 0px 10px; position: relative;&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;39&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;span style=&quot;color: white;&quot;&gt;Build a practitioner-focused reference for quant developers that connects products, pricing, risk, market data, numerical methods, and production architecture.&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;41&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This is not meant to be read cover to cover like a course.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;43&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It is designed to work as:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a reference you can return to when building something real,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;45&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a bridge between theory and implementation,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;46&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a map of how the major pieces fit together,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;47&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and a foundation that can keep growing over time.&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;49&quot; dir=&quot;auto&quot; id=&quot;what-is-in-the-repo&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What Is In The Repo&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;51&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The library is organized to cover both the instrument side and the engineering side.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;53&quot; dir=&quot;auto&quot; id=&quot;core-product-chapters&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;Core product chapters&lt;/h3&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;options,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;futures and forwards,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;equities,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;57&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;FX,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;58&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;fixed income,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;interest rates,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;60&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;credit,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;61&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;commodities,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;62&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and cross-asset topics.&lt;/li&gt;&lt;/ul&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;64&quot; dir=&quot;auto&quot; id=&quot;quant-engineering-chapters&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;Quant engineering chapters&lt;/h3&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;market data,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;66&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;pricing architecture,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;risk and PnL,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;68&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;testing and validation,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;69&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;performance and production.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;71&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;There is also a numerical methods chapter because, in practice, almost every serious pricing problem ends up there eventually.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;73&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The idea is that a quant developer should not need to mentally separate:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;74&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;74&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&quot;the finance part,&quot;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;75&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&quot;the code part,&quot;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;76&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and &quot;the production part.&quot;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;78&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Those are usually the same problem, just seen from different angles.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;80&quot; dir=&quot;auto&quot; id=&quot;the-point-of-view&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Point Of View&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;82&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This repo is opinionated.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;84&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It assumes that quantitative correctness is not just about deriving the right formula. It is also about:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;85&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;85&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;using the right conventions,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;86&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;consuming the right market data,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;87&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;choosing the right numerical method,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;88&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;exposing the right risk,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;89&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and building the system so the result is reproducible and explainable.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;91&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is why the library focuses on questions like:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;What does the desk actually quote?&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;93&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;What data do you really need?&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;94&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;What assumptions are hidden in this model?&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;95&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;What tends to break in production?&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;How should this be tested?&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;97&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;How do you know the output is sane?&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;99&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Those questions matter just as much as the equation itself.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;101&quot; dir=&quot;auto&quot; id=&quot;who-it-is-for&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Who It Is For&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;103&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I built this primarily for:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;104&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;104&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;quant developers,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;105&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;engineering-minded quants,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;106&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;developers moving into front-office or analytics roles,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;107&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and practitioners who want a more implementation-grounded way to study the field.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;109&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you are preparing for interviews, building pricing libraries, working on market data or risk systems, or trying to connect multiple years of learning into one coherent framework, this should be useful.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;111&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It should also be useful to people already in the field who want a clean reference instead of searching across old notes and half-remembered documents.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;113&quot; dir=&quot;auto&quot; id=&quot;what-makes-it-different&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What Makes It Different&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;There are plenty of resources that explain option pricing. There are plenty of resources that explain fixed income. There are plenty of resources that explain numerical methods.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;What is rarer is a resource that keeps all of the following in the same frame:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;120&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;120&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;product intuition,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;121&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;pricing formulas,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;122&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;market conventions,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;123&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;implementation shape,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;124&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;validation logic,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;125&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and production pitfalls.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;127&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is the standard I want this repository to meet.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;For example, an options chapter should not stop at Black-Scholes. It should also talk about:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;130&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;130&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;implied volatility surfaces,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;131&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;no-arbitrage checks,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;132&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;surface risk conventions,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;American exercise intuition,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;134&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;implementation pitfalls,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and the difference between a formula that works on paper and an analytics workflow that works on a desk.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;137&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The same standard applies across rates, fixed income, credit, market data, risk, and architecture.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;139&quot; dir=&quot;auto&quot; id=&quot;why-i-am-sharing-it-early&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why I Am Sharing It Early&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;141&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I do not want this to become a private note system that only becomes visible once it is &quot;finished.&quot;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;A library like this gets better in the open.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;145&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It improves when people use it, challenge it, extend it, and point out where the real complexity lives. Quant development is too broad, too practical, and too experience-driven for one person to pretend they can write the final word on it alone.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;147&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;So I am sharing it as a growing public reference.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;149&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The current version already has the foundation:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;150&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;150&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a consistent structure,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;151&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;broad chapter coverage,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;152&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;deeper treatment in options, fixed income, rates, and numerical methods,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;153&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and dedicated chapters for the engineering side of quant work.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;155&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;From here, the plan is to keep making it more useful.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;157&quot; dir=&quot;auto&quot; id=&quot;where-i-want-to-take-it&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Where I Want To Take It&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;159&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Over time, I want this repository to become a serious long-term resource for the quant developer community.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;161&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That means:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;deeper product coverage,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;163&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;better worked examples,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;164&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;more implementation patterns,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;165&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;more sanity-check frameworks,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;166&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;stronger cross-links between topics,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;167&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and eventually a body of material that is genuinely useful both for study and for real-world system design.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;169&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Some of the areas I especially want to deepen:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;170&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;170&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;volatility modelling,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;171&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;multi-curve rates,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;172&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;fixed-income relative value and spread analytics,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;173&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;calibration workflows,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;174&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;pricing architecture patterns,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;175&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;risk explain,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;176&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and the operational side of production quant systems.&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;178&quot; dir=&quot;auto&quot; id=&quot;if-you-work-in-this-space&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;If You Work In This Space&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;180&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you are a quant developer, quant, trader, or engineer working near pricing and risk systems, I would love for you to take a look.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;182&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Use it. Challenge it. Steal from it. Improve it.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;187&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If a section is missing something important, I want to know. If a convention should be clarified, I want to know. If there is a subtle implementation trap that every real system hits, that is exactly the kind of knowledge worth capturing here.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;191&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The best technical references are not just correct. They are useful.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;193&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is the bar.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;195&quot; dir=&quot;auto&quot; id=&quot;repository&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Repository&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;197&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If this sounds useful, you can explore the repo here:&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;199&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;strong&gt;Quantitative Developer Reference Library&lt;/strong&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;201&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Start with:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;202&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;202&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;README.md&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;203&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;00-overview.md&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;204&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;01-options.md&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;205&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;05-fixed-income.md&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;206&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;06-interest-rates.md&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;207&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;10-numerical-methods.md&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;209&quot; dir=&quot;auto&quot; id=&quot;closing-thought&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Closing Thought&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;211&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Quant finance has no shortage of complexity. What it often lacks is structure.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;214&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The point of this library is to create more structure:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;215&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;215&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;structure around the products,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;216&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;structure around the implementation,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;217&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;structure around the failure modes,&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;218&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;and structure around the knowledge itself.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;220&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If it saves someone time, helps someone build something better, or gives the community a shared reference that is more practical than what already exists, then it is worth doing.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;222&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is the project.&lt;/p&gt;&lt;hr class=&quot;code-line&quot; data-line=&quot;224&quot; dir=&quot;auto&quot; style=&quot;border-bottom-color: rgba(255, 255, 255, 0.18); border-bottom-style: solid; border-image: initial; border-left: 0px rgba(255, 255, 255, 0.18); border-right: 0px rgba(255, 255, 255, 0.18); border-top: 0px rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; height: 1px; position: relative;&quot; /&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;226&quot; dir=&quot;auto&quot; id=&quot;short-version-for-social-posts&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Short Version For Social Posts&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;228&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I built a&amp;nbsp;&lt;strong&gt;Quantitative Developer Reference Library&lt;/strong&gt;: a practical, growing repo for quant developers that connects products, pricing, risk, market data, numerical methods, and production architecture.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;230&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It is designed to bridge the gap between &quot;I know the formula&quot; and &quot;I can build this properly.&quot;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;232&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Current coverage includes options, futures, equities, FX, fixed income, rates, credit, commodities, cross-asset topics, plus market data, pricing architecture, risk/PnL, testing, and production engineering.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;234&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you work in quant dev, pricing, risk, or analytics engineering, I would love feedback.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/04/building-quant-developer-reference.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbOhavBnCgK2-8XdJdGE0nYsZp8vtXe3usDHnH0MNWZLJO5pPRrjEyVw2nO-Dw7oVyTazsxY9D3NjuukB_QzbfovdZ0Wqwu7i1y0p3DB-H1vCpzvryf7bHXQJiWbI1-cHxQ1G5NbN-or6mfai3KgtGbk6SHZlAFnPnJcdH6c50sWCt_PqbfTFYo7zxwQE/s72-c/ChatGPT%20Image%20Apr%207,%202026,%2010_38_15%20AM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-4080647754098520486</guid><pubDate>Tue, 07 Apr 2026 07:36:00 +0000</pubDate><atom:updated>2026-04-07T07:36:36.241+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">fireworks</category><category domain="http://www.blogger.com/atom/ns#">fun</category><category domain="http://www.blogger.com/atom/ns#">Python</category><category domain="http://www.blogger.com/atom/ns#">simulation</category><title>Building a CLI Firework Simulation in Python, Just for Fun</title><description>&lt;p&gt;&lt;span style=&quot;font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiG3RcTc2sCT69obRO63RZIOjLgep_9EsFbq4rbf55mmPALg-km4A1R1UlKYGXtzqJzxIRpEWyVsgT4vYC97EneLjI0h9loB0DmZL6ThafWAYKE1W4cw7tTvfV4UNnWHpvq3yqNJbOjoJxCf015afngaPI67b6ZIJCbnyaTShnqNc2IQEmj6ilAw7Yea68&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;408&quot; data-original-width=&quot;871&quot; height=&quot;188&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiG3RcTc2sCT69obRO63RZIOjLgep_9EsFbq4rbf55mmPALg-km4A1R1UlKYGXtzqJzxIRpEWyVsgT4vYC97EneLjI0h9loB0DmZL6ThafWAYKE1W4cw7tTvfV4UNnWHpvq3yqNJbOjoJxCf015afngaPI67b6ZIJCbnyaTShnqNc2IQEmj6ilAw7Yea68=w400-h188&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Every now and then it is worth building something with no real business value at all.&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/JordiCorbilla/firework-simulation&quot;&gt;JordiCorbilla/firework-simulation: firework-simulation&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;This terminal firework simulation was one of those projects.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyuRxe_KM9Q-dKlxe-3-Bvug79jjPpXkz95iCGtaaob6X0LhWeBmxs9j1CILUTrTe5SgWR93QP5_w55_m67PbsUItg4A8jEeSWEehotHPhypi1K7xRnH5obeqiKH-ZwvjFlk6zDlgAo3W-C3DMO8ckCFnetVL4v5M9kl0g8HOUDu8R3wmx183LCfCE1RM/s957/fireworks.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;685&quot; data-original-width=&quot;957&quot; height=&quot;458&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyuRxe_KM9Q-dKlxe-3-Bvug79jjPpXkz95iCGtaaob6X0LhWeBmxs9j1CILUTrTe5SgWR93QP5_w55_m67PbsUItg4A8jEeSWEehotHPhypi1K7xRnH5obeqiKH-ZwvjFlk6zDlgAo3W-C3DMO8ckCFnetVL4v5M9kl0g8HOUDu8R3wmx183LCfCE1RM/w640-h458/fireworks.gif&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;It was not meant to be a serious graphics engine, a physics experiment, or a polished game. It was just a fun idea: could a terminal window, a handful of ASCII characters, and some ANSI colors feel enough like fireworks to make me smile? The answer turned out to be yes.&lt;/p&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;The basic idea is simple. A rocket launches from the bottom of the terminal, rises with velocity and gravity, bursts near its apex, and then scatters particles across the screen. Those particles fade out over time, slow down slightly, and disappear. Render that fast enough in a loop and you get something that feels lively, colourful, and surprisingly expressive for such a low-tech medium.&lt;/p&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;What makes a project like this enjoyable is that the constraints are part of the charm. A terminal is a terrible place for realistic animation. Resolution is coarse, circles are approximate, motion is chunky, and different terminals behave differently. But that is exactly why the project works best as a stylized effect rather than a realistic one. Bright colours, simple trails, exaggerated bursts, and particles fading from&amp;nbsp;&lt;span class=&quot;_inlineMarkdown_3nxm6_25 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60&quot; style=&quot;--tw-leading: 1 !important; background-color: oklab(0.845175 0.0000383258 0.0000169277 / 0.1); border-radius: 7.5px; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 1 !important; margin: 0px; padding-block: 2px; padding-inline: 6px; padding: 0px;&quot;&gt;@&lt;/span&gt;&amp;nbsp;to&amp;nbsp;&lt;span class=&quot;_inlineMarkdown_3nxm6_25 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60&quot; style=&quot;--tw-leading: 1 !important; background-color: oklab(0.845175 0.0000383258 0.0000169277 / 0.1); border-radius: 7.5px; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 1 !important; margin: 0px; padding-block: 2px; padding-inline: 6px; padding: 0px;&quot;&gt;o&lt;/span&gt;&amp;nbsp;to&amp;nbsp;&lt;span class=&quot;_inlineMarkdown_3nxm6_25 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60&quot; style=&quot;--tw-leading: 1 !important; background-color: oklab(0.845175 0.0000383258 0.0000169277 / 0.1); border-radius: 7.5px; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 1 !important; margin: 0px; padding-block: 2px; padding-inline: 6px; padding: 0px;&quot;&gt;*&lt;/span&gt;&amp;nbsp;to&amp;nbsp;&lt;span class=&quot;_inlineMarkdown_3nxm6_25 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60&quot; style=&quot;--tw-leading: 1 !important; background-color: oklab(0.845175 0.0000383258 0.0000169277 / 0.1); border-radius: 7.5px; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 1 !important; margin: 0px; padding-block: 2px; padding-inline: 6px; padding: 0px;&quot;&gt;.&lt;/span&gt;&amp;nbsp;do more for the effect than realism ever could.&lt;/p&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;The implementation uses plain Python and ANSI escape codes, which keeps it lightweight and easy to run. There is a render loop, a small particle system, a few burst patterns, and some keyboard controls for launching rockets, triggering bursts, toggling finale mode, pausing, and quitting. Nothing too deep. Just enough structure to make the show feel varied.&lt;/p&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;I also leaned into the playful side of it. There are different shell patterns like chrysanthemum, ring, willow, palm, and crackle. Rockets leave trails. The background has stars. There is an automatic finale mode that ramps up the pace. None of this was necessary. That was the point.&lt;/p&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;Projects like this are a good reminder that programming does not always need to be optimized around utility. Sometimes it is enough to build something because it is amusing, visually satisfying, or slightly ridiculous. A CLI firework show definitely qualifies.&lt;/p&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;In the end, this was just for fun, and that is exactly why it was worth making.&lt;/p&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;If you want to try it yourself, run:&lt;/p&gt;&lt;div class=&quot;bg-token-text-code-block-background border-token-input-background relative overflow-clip rounded-lg border contain-inline-size dark my-2&quot; data-theme=&quot;dark&quot; style=&quot;--tw-contain-size: inline-size; background-color: rgba(10, 10, 10, 0.4); border-radius: 12.5px; border: 1px solid rgb(60, 60, 60); box-sizing: border-box; contain: inline-size; corner-shape: superellipse(1.5); font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; margin-block: 8px; margin: 0px; overflow: clip; padding: 0px; position: relative;&quot;&gt;&lt;div class=&quot;text-size-chat overflow-y-auto p-2&quot; dir=&quot;ltr&quot; style=&quot;border: 0px solid; box-sizing: border-box; margin: 0px; overflow-y: auto; padding: 8px; scrollbar-color: rgba(121, 121, 121, 0.4) rgba(0, 0, 0, 0);&quot;&gt;&lt;code class=&quot;whitespace-pre!&quot; style=&quot;background-color: unset !important; border-radius: 0px !important; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-feature-settings: normal; font-size: 1em; font-variation-settings: normal; margin: 0px; padding: 0px !important; white-space: pre !important;&quot;&gt;python -m fireworks
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;And if you want to interact with it:&lt;/p&gt;&lt;ul class=&quot;text-size-chat leading-relaxed extension:leading-normal mt-0 mb-4  list-disc pl-4&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; list-style-image: initial; list-style-position: initial; margin: 0px 0px 16px; padding: 0px 0px 0px 16px;&quot;&gt;&lt;li class=&quot;text-size-chat leading-relaxed extension:leading-normal mb-1.5&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; line-height: 1.5; margin: 0px 0px 6px; padding: 0px;&quot;&gt;&lt;span class=&quot;_inlineMarkdown_3nxm6_25 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60&quot; style=&quot;--tw-leading: 1 !important; background-color: oklab(0.845175 0.0000383258 0.0000169277 / 0.1); border-radius: 7.5px; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 1 !important; margin: 0px; padding-block: 2px; padding-inline: 6px; padding: 0px;&quot;&gt;space&lt;/span&gt;&amp;nbsp;launches a rocket&lt;/li&gt;&lt;li class=&quot;text-size-chat leading-relaxed extension:leading-normal mb-1.5&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; line-height: 1.5; margin: 0px 0px 6px; padding: 0px;&quot;&gt;&lt;span class=&quot;_inlineMarkdown_3nxm6_25 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60&quot; style=&quot;--tw-leading: 1 !important; background-color: oklab(0.845175 0.0000383258 0.0000169277 / 0.1); border-radius: 7.5px; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 1 !important; margin: 0px; padding-block: 2px; padding-inline: 6px; padding: 0px;&quot;&gt;r&lt;/span&gt;&amp;nbsp;triggers a random burst&lt;/li&gt;&lt;li class=&quot;text-size-chat leading-relaxed extension:leading-normal mb-1.5&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; line-height: 1.5; margin: 0px 0px 6px; padding: 0px;&quot;&gt;&lt;span class=&quot;_inlineMarkdown_3nxm6_25 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60&quot; style=&quot;--tw-leading: 1 !important; background-color: oklab(0.845175 0.0000383258 0.0000169277 / 0.1); border-radius: 7.5px; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 1 !important; margin: 0px; padding-block: 2px; padding-inline: 6px; padding: 0px;&quot;&gt;f&lt;/span&gt;&amp;nbsp;toggles finale mode&lt;/li&gt;&lt;li class=&quot;text-size-chat leading-relaxed extension:leading-normal mb-1.5&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; line-height: 1.5; margin: 0px 0px 6px; padding: 0px;&quot;&gt;&lt;span class=&quot;_inlineMarkdown_3nxm6_25 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60&quot; style=&quot;--tw-leading: 1 !important; background-color: oklab(0.845175 0.0000383258 0.0000169277 / 0.1); border-radius: 7.5px; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 1 !important; margin: 0px; padding-block: 2px; padding-inline: 6px; padding: 0px;&quot;&gt;p&lt;/span&gt;&amp;nbsp;pauses&lt;/li&gt;&lt;li class=&quot;text-size-chat leading-relaxed extension:leading-normal mb-1.5&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; line-height: 1.5; margin: 0px 0px 6px; padding: 0px;&quot;&gt;&lt;span class=&quot;_inlineMarkdown_3nxm6_25 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60&quot; style=&quot;--tw-leading: 1 !important; background-color: oklab(0.845175 0.0000383258 0.0000169277 / 0.1); border-radius: 7.5px; border: 0px solid; box-sizing: border-box; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 12px; line-height: 1 !important; margin: 0px; padding-block: 2px; padding-inline: 6px; padding: 0px;&quot;&gt;q&lt;/span&gt;&amp;nbsp;quits&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;text-size-chat leading-relaxed extension:leading-normal my-2&quot; style=&quot;--tw-leading: 1.5; border: 0px solid; box-sizing: border-box; font-family: &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, sans-serif; font-size: 13px; line-height: 1.5; margin-block: 8px; margin: 0px; padding: 0px;&quot;&gt;It is a small project, but it captures something I like about programming: sometimes a silly idea is reason enough.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/04/building-cli-firework-simulation-in.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEiG3RcTc2sCT69obRO63RZIOjLgep_9EsFbq4rbf55mmPALg-km4A1R1UlKYGXtzqJzxIRpEWyVsgT4vYC97EneLjI0h9loB0DmZL6ThafWAYKE1W4cw7tTvfV4UNnWHpvq3yqNJbOjoJxCf015afngaPI67b6ZIJCbnyaTShnqNc2IQEmj6ilAw7Yea68=s72-w400-h188-c" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-5933550275974143162</guid><pubDate>Tue, 07 Apr 2026 07:25:00 +0000</pubDate><atom:updated>2026-04-07T07:25:01.653+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">gemma 4</category><category domain="http://www.blogger.com/atom/ns#">Local LLM</category><category domain="http://www.blogger.com/atom/ns#">mobile device</category><title>Running Gemma 4 Locally on Android: Surprisingly Good</title><description>&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ9p5zMtIkYPtQvrHr9uN631YM4acYRXJQhEattigQMynJtERXnItMH969TEa2SDpdxCOBDAFOsq_BXI6UqoKtmAZTCSzeRkP5gSNTX2bxu7i4VimncFVh-6kG_F7RrxAHaocrueORRwNPofHqhVcbqG3UYpWzE_yX_PB4rk3Jwyi9rQaBEjEiV6_tvW8/s1536/ChatGPT%20Image%20Apr%207,%202026,%2008_18_31%20AM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ9p5zMtIkYPtQvrHr9uN631YM4acYRXJQhEattigQMynJtERXnItMH969TEa2SDpdxCOBDAFOsq_BXI6UqoKtmAZTCSzeRkP5gSNTX2bxu7i4VimncFVh-6kG_F7RrxAHaocrueORRwNPofHqhVcbqG3UYpWzE_yX_PB4rk3Jwyi9rQaBEjEiV6_tvW8/s320/ChatGPT%20Image%20Apr%207,%202026,%2008_18_31%20AM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;I’ve been experimenting with on-device LLMs for a while—mostly via Ollama, OpenClaw, and various local inference stacks—but this is the first time I’ve seen something that feels &lt;em&gt;actually usable&lt;/em&gt; on a phone without compromise.&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;I just tested &lt;strong&gt;Gemma 4 (E2B-it variant)&lt;/strong&gt; directly on Android, and the experience is… unexpectedly solid.&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;TL;DR&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Area&lt;/th&gt;&lt;th&gt;Verdict&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Setup&lt;/td&gt;&lt;td&gt;Extremely simple (native integration)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Performance&lt;/td&gt;&lt;td&gt;Fast enough to feel interactive&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Quality&lt;/td&gt;&lt;td&gt;Strong for a ~2.5GB model&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UX&lt;/td&gt;&lt;td&gt;Clean, minimal, no friction&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Practicality&lt;/td&gt;&lt;td&gt;Finally viable for real usage&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;What This Is&lt;/h2&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This is Google’s &lt;strong&gt;Gemma 4 model running fully on-device&lt;/strong&gt;, exposed through an Android-native interface using LiteRT-LM.&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Key characteristics:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;&lt;strong&gt;~2.5GB footprint&lt;/strong&gt; (E2B-it variant)&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Runs entirely locally&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Supports multimodal input&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;~32K context window&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;No cloud dependency&lt;/li&gt;&lt;li&gt;No latency spikes from network&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This matters more than it sounds—because most “local LLM” setups are either:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Too heavy (desktop GPU required), or&lt;/li&gt;&lt;li&gt;Too slow (toy-level mobile inference)&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This sits right in the middle: &lt;em&gt;practical local intelligence&lt;/em&gt;.&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;First Impressions&lt;/h2&gt;&lt;h3&gt;1. Setup Experience&lt;/h3&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This is where it stands out immediately.&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;No:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Docker&lt;/li&gt;&lt;li&gt;Python envs&lt;/li&gt;&lt;li&gt;CUDA nonsense&lt;/li&gt;&lt;li&gt;CLI gymnastics&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Just:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Open app&lt;/li&gt;&lt;li&gt;Tap download&lt;/li&gt;&lt;li&gt;Done&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg0PBu5xp4yYMry9TYl9AMhLJXrjg_QwdUWnIl6Rzwyj_6AXFgBjtZsxQ-pV9RsKEjTSFpsrscf1vx6O8u-CRL-HJ-b4xjcFt8vkgZbjrGYor9DXmF3C-MvIFzxbXWyFYXG6OpyM0OriKo1kt_9Ia7zLcIESb0ykODco0Hllcce8EyFcFneofQO3NtnBVY&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;2048&quot; data-original-width=&quot;921&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg0PBu5xp4yYMry9TYl9AMhLJXrjg_QwdUWnIl6Rzwyj_6AXFgBjtZsxQ-pV9RsKEjTSFpsrscf1vx6O8u-CRL-HJ-b4xjcFt8vkgZbjrGYor9DXmF3C-MvIFzxbXWyFYXG6OpyM0OriKo1kt_9Ia7zLcIESb0ykODco0Hllcce8EyFcFneofQO3NtnBVY=w288-h640&quot; width=&quot;288&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Compared to typical local setups (Ollama, llama.cpp, etc.), this is &lt;strong&gt;orders of magnitude simpler&lt;/strong&gt;.&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h3&gt;2. Performance&lt;/h3&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This is the surprising part.&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Responses are &lt;strong&gt;fast enough to feel conversational&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;No obvious stalling or token starvation&lt;/li&gt;&lt;li&gt;Latency feels closer to edge inference than “local hack”&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This suggests:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Aggressive quantization&lt;/li&gt;&lt;li&gt;Optimized runtime (LiteRT-LM is doing heavy lifting here)&lt;/li&gt;&lt;li&gt;Likely hardware acceleration (NNAPI / GPU paths)&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;It’s not desktop-level—but it’s &lt;em&gt;good enough to actually use&lt;/em&gt;.&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h3&gt;3. Model Quality&lt;/h3&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;For a &lt;strong&gt;2.5GB model&lt;/strong&gt;, the quality is impressive:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Coherent reasoning&lt;/li&gt;&lt;li&gt;Good instruction following&lt;/li&gt;&lt;li&gt;Decent structure in responses&lt;/li&gt;&lt;li&gt;No obvious collapse under moderate prompts&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Where it likely struggles (as expected):&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Deep multi-step reasoning&lt;/li&gt;&lt;li&gt;Heavy coding tasks&lt;/li&gt;&lt;li&gt;Long-chain logical consistency&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;But for:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Notes&lt;/li&gt;&lt;li&gt;Quick analysis&lt;/li&gt;&lt;li&gt;Idea generation&lt;/li&gt;&lt;li&gt;Lightweight coding help&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;…it’s absolutely viable.&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEitSfbVA8TGJCjaJ99Oh4RulVwoJifKGq8q83iOtN0uW4HUqZxD57t9J931GviUYtpVuv14IreHkXKtzOHtBtKtAXg9KCa1VMK3YZ6RlYfhZ8V7l2sF0E3yjCWu0zLx8Bq4Vd6zPBYh3fgOWt4JaMSK2s2-Msw3SminhGsLPW8UPHgYXoJCsivovtshD2I&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;2048&quot; data-original-width=&quot;921&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEitSfbVA8TGJCjaJ99Oh4RulVwoJifKGq8q83iOtN0uW4HUqZxD57t9J931GviUYtpVuv14IreHkXKtzOHtBtKtAXg9KCa1VMK3YZ6RlYfhZ8V7l2sF0E3yjCWu0zLx8Bq4Vd6zPBYh3fgOWt4JaMSK2s2-Msw3SminhGsLPW8UPHgYXoJCsivovtshD2I=w288-h640&quot; width=&quot;288&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;Why This Matters (Strategically)&lt;/h2&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This is bigger than just “cool mobile AI”.&lt;/p&gt;&lt;h3&gt;1. True Edge AI Is Finally Here&lt;/h3&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;We’re crossing a threshold:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Before&lt;/td&gt;&lt;td&gt;Now&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Cloud-only intelligence&lt;/td&gt;&lt;td&gt;Local-first viable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Privacy tradeoffs&lt;/td&gt;&lt;td&gt;Fully private inference&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Latency issues&lt;/td&gt;&lt;td&gt;Instant response&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;API costs&lt;/td&gt;&lt;td&gt;Zero marginal cost&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This changes:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Enterprise workflows&lt;/li&gt;&lt;li&gt;Personal productivity&lt;/li&gt;&lt;li&gt;Privacy models&lt;/li&gt;&lt;/ul&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h3&gt;2. Cost Model Disruption&lt;/h3&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;If you can run:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;A &lt;strong&gt;good-enough model locally&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;With zero infra cost&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Then:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Not every task needs GPT-5 / Claude Opus&lt;/li&gt;&lt;li&gt;You offload 70–80% of interactions locally&lt;/li&gt;&lt;li&gt;Cloud becomes &lt;em&gt;premium tier&lt;/em&gt;, not default&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This is exactly the direction your current stack (OpenClaw + Ollama) is already heading—this just compresses it into mobile.&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h3&gt;3. UX Is the Real Breakthrough&lt;/h3&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;The real innovation here is not the model—it’s the &lt;strong&gt;delivery&lt;/strong&gt;.&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Compare:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Stack&lt;/td&gt;&lt;td&gt;Friction&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Ollama + CLI&lt;/td&gt;&lt;td&gt;Medium&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;OpenClaw + agents&lt;/td&gt;&lt;td&gt;High (powerful but complex)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Android Gemma app&lt;/td&gt;&lt;td&gt;Near zero&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Who wins?&lt;br /&gt;The one users can install in 30 seconds.&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;Where It Fits in a Serious Stack&lt;/h2&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Given your current setup (agentic + local infra), this opens interesting architecture options:&lt;/p&gt;&lt;h3&gt;Hybrid Model Strategy&lt;/h3&gt;&lt;ul data-spread=&quot;true&quot;&gt;&lt;li&gt;&lt;strong&gt;Mobile (Gemma 4)&lt;/strong&gt;&lt;br /&gt;→ Quick queries, notes, offline usage&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Local Desktop (Ollama / OpenClaw)&lt;/strong&gt;&lt;br /&gt;→ Agent workflows, automation, coding&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Cloud (Claude / GPT)&lt;/strong&gt;&lt;br /&gt;→ Heavy reasoning, critical tasks&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This becomes a &lt;strong&gt;tiered inference system&lt;/strong&gt;:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Cheap → Fast → Local&lt;/li&gt;&lt;li&gt;Expensive → Smart → Cloud&lt;/li&gt;&lt;/ul&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;Limitations (Be Realistic)&lt;/h2&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This is not magic.&lt;/p&gt;&lt;h3&gt;Constraints:&lt;/h3&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Memory-bound → limited reasoning depth&lt;/li&gt;&lt;li&gt;Smaller parameter count → weaker abstraction&lt;/li&gt;&lt;li&gt;Likely struggles with:&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;complex code generation&lt;/li&gt;&lt;li&gt;financial modelling&lt;/li&gt;&lt;li&gt;deep system design&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Hidden Tradeoffs:&lt;/h3&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Quantization artifacts&lt;/li&gt;&lt;li&gt;Potential hallucination under pressure&lt;/li&gt;&lt;li&gt;Performance tied to device hardware&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Still—none of these are deal-breakers for its target use.&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;Opinionated Take&lt;/h2&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;This is the first time I’d say:&lt;/p&gt;&lt;blockquote&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;&lt;strong&gt;Local LLMs on mobile are no longer a gimmick.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;We’re not at parity with cloud models—but we don’t need to be.&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;We just need:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;70% of capability&lt;/li&gt;&lt;li&gt;0% latency&lt;/li&gt;&lt;li&gt;0% cost&lt;/li&gt;&lt;li&gt;100% privacy&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;And this hits that balance.&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;What I’d Do Next (If You Want to Push This Further)&lt;/h2&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Given your background, this is where it gets interesting:&lt;/p&gt;&lt;h3&gt;1. Build a Mobile → Agent Bridge&lt;/h3&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Phone handles prompts locally&lt;/li&gt;&lt;li&gt;Escalates complex tasks to your OpenClaw backend&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;2. Local RAG on Mobile&lt;/h3&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Index notes / PDFs on-device&lt;/li&gt;&lt;li&gt;Use Gemma as query layer&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;3. Trading / Quant Use Case (Lightweight)&lt;/h3&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Quick portfolio queries&lt;/li&gt;&lt;li&gt;Market summaries (cached locally)&lt;/li&gt;&lt;li&gt;Decision journaling&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;4. Telegram Bot + Mobile LLM Hybrid&lt;/h3&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Local inference first&lt;/li&gt;&lt;li&gt;Cloud fallback only when needed&lt;/li&gt;&lt;/ul&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;Final Verdict&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Dimension&lt;/td&gt;&lt;td&gt;Score&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Innovation&lt;/td&gt;&lt;td&gt;8/10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Practicality&lt;/td&gt;&lt;td&gt;9/10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Performance&lt;/td&gt;&lt;td&gt;7.5/10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UX&lt;/td&gt;&lt;td&gt;9.5/10&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Strategic impact&lt;/td&gt;&lt;td&gt;9/10&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;&lt;strong&gt;This is the direction everything is going.&lt;/strong&gt;&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;Not bigger models.&lt;br /&gt;Not more GPUs.&lt;/p&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;&lt;strong&gt;Smarter distribution of intelligence across edge + cloud.&lt;/strong&gt;&lt;/p&gt;&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr /&gt;&lt;/div&gt;&lt;h2&gt;Closing Thought&lt;/h2&gt;&lt;p class=&quot;isSelectedEnd&quot;&gt;If this trajectory continues:&lt;/p&gt;&lt;ul data-spread=&quot;false&quot;&gt;&lt;li&gt;Your phone becomes your &lt;strong&gt;primary AI interface&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Your laptop becomes your &lt;strong&gt;agent orchestration layer&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;The cloud becomes &lt;strong&gt;optional, not required&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;That’s a very different world than where we were even 12 months ago.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/04/running-gemma-4-locally-on-android.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ9p5zMtIkYPtQvrHr9uN631YM4acYRXJQhEattigQMynJtERXnItMH969TEa2SDpdxCOBDAFOsq_BXI6UqoKtmAZTCSzeRkP5gSNTX2bxu7i4VimncFVh-6kG_F7RrxAHaocrueORRwNPofHqhVcbqG3UYpWzE_yX_PB4rk3Jwyi9rQaBEjEiV6_tvW8/s72-c/ChatGPT%20Image%20Apr%207,%202026,%2008_18_31%20AM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-4634772013518407785</guid><pubDate>Sun, 05 Apr 2026 13:31:00 +0000</pubDate><atom:updated>2026-04-05T15:44:00.433+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">MCP Client</category><category domain="http://www.blogger.com/atom/ns#">MCP Server</category><category domain="http://www.blogger.com/atom/ns#">openAI</category><category domain="http://www.blogger.com/atom/ns#">Python</category><title>Build a Simple MCP Agent with OpenAI: Describe and OCR Local Images</title><description>&lt;p&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-size: 14px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGEOsahzZJdHXGtOmONmo7SBtOeLHZ068Ok4p1r_XBHBlRg1YFIce7DyfY88vbIO9799DOaK7XB68AaxMbTH8qzvnXawUvOHwBZPXTmbZQT5Pm93yopDQoJ5B8iZY3i-o6pByjS8uYCvoWZSt8g0IrRW4P3Gw7bgYSOoHDwUWWv5Q4Ra0kRjwQb7NSlsE/s1536/ChatGPT%20Image%20Apr%205,%202026,%2002_29_25%20PM.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGEOsahzZJdHXGtOmONmo7SBtOeLHZ068Ok4p1r_XBHBlRg1YFIce7DyfY88vbIO9799DOaK7XB68AaxMbTH8qzvnXawUvOHwBZPXTmbZQT5Pm93yopDQoJ5B8iZY3i-o6pByjS8uYCvoWZSt8g0IrRW4P3Gw7bgYSOoHDwUWWv5Q4Ra0kRjwQb7NSlsE/s320/ChatGPT%20Image%20Apr%205,%202026,%2002_29_25%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;If you want a practical MCP example that is easy to run and easy to explain, image analysis is a great fit.&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Source code:&amp;nbsp;&lt;a href=&quot;https://github.com/JordiCorbilla/mcp-image-analysis-agent&quot;&gt;JordiCorbilla/mcp-image-analysis-agent: mcp-image-analysis-agent&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;In this walkthrough, we will build a minimal Model Context Protocol (MCP) setup:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;An MCP server that exposes tools to list images, download files, and analyse local images&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;7&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;An MCP client that uses OpenAI tool-calling to decide when to call that tool&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;A CLI flow that returns both:&lt;ul class=&quot;code-line&quot; data-line=&quot;9&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 0px; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;9&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;image description&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;extracted text (OCR)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This example is intentionally small so you can publish it, teach it, and extend it quickly.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; id=&quot;what-you-will-build&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What You Will Build&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;You will run two Python programs:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;server.py&lt;/code&gt;: MCP server with practical tools for image workflows&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;19&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;client.py&lt;/code&gt;: OpenAI-powered agentic client that connects to the server and can invoke MCP tools&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;21&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The interesting part is the split of responsibilities:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The client handles conversation, model calls, and tool orchestration.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;24&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The server handles local file access safely and image analysis logic.&lt;/li&gt;&lt;/ol&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; id=&quot;why-this-is-a-good-mcp-example&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why This Is a Good MCP Example&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;MCP is most useful when a model needs controlled access to local capabilities. In this project:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The model cannot directly read files.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;31&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The model must call a tool exposed by your MCP server.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The server validates paths and performs the action.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That makes this architecture both practical and safer than giving direct unrestricted local access.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; id=&quot;prerequisites&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Prerequisites&lt;/h2&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Python 3.10+&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;39&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;OpenAI API key&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;A local image file in the lab folder (for example&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;sample.png&lt;/code&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot; id=&quot;project-files&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Project Files&lt;/h2&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;client.py&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;45&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;server.py&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;46&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;requirements.txt&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;48&quot; dir=&quot;auto&quot; id=&quot;install-dependencies&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Install Dependencies&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;From the lab folder:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;python &lt;span class=&quot;hljs-literal&quot;&gt;-m&lt;/span&gt; pip install &lt;span class=&quot;hljs-literal&quot;&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot; id=&quot;set-environment-variables&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Set Environment Variables&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;58&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Use a&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.env&lt;/code&gt;&amp;nbsp;file in the same folder:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-env&quot; data-line=&quot;60&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;OPENAI_API_KEY=sk-your-key-here
OPENAI_MODEL=gpt-4.1-mini
# Optional override for server-side vision model
OPENAI_VISION_MODEL=gpt-4.1-mini
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; id=&quot;run-the-demo&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Run the Demo&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;69&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Start the client and point it to the server:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;71&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;python .\client.py .\server.py
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;75&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;From the menu:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;77&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;77&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Choose&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;Analyse Local Image (Description + OCR)&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;78&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Enter an image path relative to the project folder&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;79&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Optionally add a focus instruction (for example:&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;extract receipt totals&lt;/code&gt;)&lt;/li&gt;&lt;/ol&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;81&quot; dir=&quot;auto&quot; id=&quot;how-the-agentic-loop-works&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;How the Agentic Loop Works&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;83&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The client does this repeatedly:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;85&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;85&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Sends user query + available MCP tools to OpenAI.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;86&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;If model requests tool calls, client executes them through MCP.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;87&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Tool results are appended back into the conversation.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;88&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Model returns final answer.&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;90&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That means the model decides&amp;nbsp;&lt;em&gt;when&lt;/em&gt;&amp;nbsp;to use tools, while your server decides&amp;nbsp;&lt;em&gt;how&lt;/em&gt;&amp;nbsp;tools operate.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot; id=&quot;core-mcp-tools&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Core MCP Tools&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;94&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The server exposes these core tools:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;list_images_in_current_folder()&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;97&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;download_file_from_url(url, output_path=&quot;&quot;)&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;98&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;analyze_local_image(file_path, focus=&quot;&quot;)&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;100&quot; dir=&quot;auto&quot; id=&quot;1-list-images-in-the-current-folder&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;1) List Images in the Current Folder&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;102&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Use this when you want the agent to discover available images before analysis.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;104&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Example request:&lt;/p&gt;&lt;blockquote class=&quot;code-line&quot; data-line=&quot;106&quot; dir=&quot;auto&quot; style=&quot;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(34, 34, 34); border-color: rgba(0, 122, 204, 0.5); border-left-style: solid; border-left-width: 5px; border-radius: 2px; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin: 0px; padding: 0px 16px 0px 10px; position: relative;&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;106&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;span style=&quot;color: white;&quot;&gt;List images available in this folder.&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;108&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Returned data includes:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;110&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;110&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;count&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;111&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;images[]&lt;/code&gt;&amp;nbsp;with name, relative path, size, and modified timestamp&lt;/li&gt;&lt;/ul&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;113&quot; dir=&quot;auto&quot; id=&quot;2-download-a-file-from-a-url&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;2) Download a File from a URL&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Use this to bring an image into your project folder before analysis.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Example request:&lt;/p&gt;&lt;blockquote class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot; style=&quot;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(34, 34, 34); border-color: rgba(0, 122, 204, 0.5); border-left-style: solid; border-left-width: 5px; border-radius: 2px; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin: 0px; padding: 0px 16px 0px 10px; position: relative;&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;119&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;span style=&quot;color: white;&quot;&gt;Download&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;https://example.com/photo.jpg&lt;/code&gt;&amp;nbsp;to&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;downloads/photo.jpg&lt;/code&gt;.&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;121&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The tool restricts downloads to&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;http&lt;/code&gt;/&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;https&lt;/code&gt;&amp;nbsp;and saves only inside your project directory.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;123&quot; dir=&quot;auto&quot; id=&quot;3-analyze-a-local-image&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;3) Analyse a Local Image&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;125&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This performs description + OCR in one pass.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;127&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Behaviour:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Validates the path stays inside the project directory.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;130&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Checks that the file exists and is a supported image format.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;131&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Converts image bytes to a data URL.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;132&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Sends image + instruction to OpenAI Vision.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Returns structured output:&lt;ul class=&quot;code-line&quot; data-line=&quot;134&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 0px; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;134&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;description&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;extracted_text&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;136&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;notable_details&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;138&quot; dir=&quot;auto&quot; id=&quot;example-prompt&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Example Prompt&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;140&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;User asks:&lt;/p&gt;&lt;blockquote class=&quot;code-line&quot; data-line=&quot;142&quot; dir=&quot;auto&quot; style=&quot;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(34, 34, 34); border-color: rgba(0, 122, 204, 0.5); border-left-style: solid; border-left-width: 5px; border-radius: 2px; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin: 0px; padding: 0px 16px 0px 10px; position: relative;&quot;&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;142&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;span style=&quot;color: white;&quot;&gt;Analyze image&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;sample.png&lt;/code&gt;. Use MCP tools. Return a short description, extracted text, and two useful&lt;/span&gt; follow-up actions.&lt;/p&gt;&lt;/blockquote&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;144&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;You can also run a&lt;br /&gt; two-step flow:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;146&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;146&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Ask the agent to list images with&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;list_images_in_current_folder&lt;/code&gt;.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;147&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Pick one and ask the agent to analyse it with&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;analyze_local_image&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;149&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Possible response:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;151&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;151&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Description: A photographed whiteboard with sprint tasks and dates.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;152&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Extracted text: &quot;Sprint 12, Demo Friday, Fix auth timeout&quot;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;153&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Follow-up actions:&lt;ul class=&quot;code-line&quot; data-line=&quot;154&quot; dir=&quot;auto&quot; style=&quot;margin-bottom: 0px; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;154&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Convert items into a task checklist.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;155&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Create calendar reminders for deadline lines.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;157&quot; dir=&quot;auto&quot; id=&quot;error-handling-included&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Error Handling Included&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;159&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This sample handles common failures cleanly:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;161&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;161&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Missing&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;OPENAI_API_KEY&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Invalid image path&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;163&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Path traversal attempts outside project folder&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;164&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Unsupported image extension&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;165&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Non-JSON model output fallback&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;167&quot; dir=&quot;auto&quot; id=&quot;security-notes&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Security Notes&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;169&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Even in a demo, do not skip path validation.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;171&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The server uses a safe resolver that enforces all tool file access under the project root. This prevents prompts from tricking your tool into reading arbitrary files outside the workspace.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;173&quot; dir=&quot;auto&quot; id=&quot;cost-and-model-tips&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Cost and Model Tips&lt;/h2&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;175&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;175&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Start with&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;gpt-4.1-mini&lt;/code&gt;&amp;nbsp;for lower cost.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;176&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;For higher OCR fidelity, test a stronger model in&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;OPENAI_VISION_MODEL&lt;/code&gt;.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;177&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Keep outputs concise to reduce tokens.&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;179&quot; dir=&quot;auto&quot; id=&quot;troubleshooting&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Troubleshooting&lt;/h2&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;181&quot; dir=&quot;auto&quot; id=&quot;openai_api_key-is-not-set&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;OPENAI_API_KEY is not set&lt;/code&gt;&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;183&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Add the key to&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.env&lt;/code&gt;&amp;nbsp;or set it in your shell, then restart.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;185&quot; dir=&quot;auto&quot; id=&quot;image-file-not-found&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;Image file not found&lt;/code&gt;&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;187&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Use a path relative to the project folder where you run the client.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;189&quot; dir=&quot;auto&quot; id=&quot;unsupported-image-extension&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;Unsupported image extension&lt;/code&gt;&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;191&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Use one of:&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.png&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.jpg&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.jpeg&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.webp&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.gif&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.bmp&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.tif&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.tiff&lt;/code&gt;.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;193&quot; dir=&quot;auto&quot; id=&quot;no-ocr-text-returned&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;No OCR text returned&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;195&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Some images contain no readable text or low-quality text. Try a clearer image or add focus guidance.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;197&quot; dir=&quot;auto&quot; id=&quot;extension-ideas&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Extension Ideas&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;199&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Once this baseline works, you can add:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;201&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;201&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Batch image processing folder mode.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;202&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Structured OCR outputs (fields for receipts/invoices/forms).&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;203&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;A second tool to summarize OCR into action items.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;204&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Markdown report generation from analysis results.&lt;/li&gt;&lt;/ol&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;206&quot; dir=&quot;auto&quot; id=&quot;final-thoughts&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Final Thoughts&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;208&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This project is a compact, publishable MCP example that demonstrates real agent behaviour:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;210&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;210&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;OpenAI handles reasoning and tool decisions.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;211&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;MCP exposes local capabilities safely.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;212&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;You get immediately useful output from local images.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;214&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you are teaching MCP, this is a strong first demo before moving on to multi-tool, multi-agent workflows.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/04/build-simple-mcp-agent-with-openai.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGEOsahzZJdHXGtOmONmo7SBtOeLHZ068Ok4p1r_XBHBlRg1YFIce7DyfY88vbIO9799DOaK7XB68AaxMbTH8qzvnXawUvOHwBZPXTmbZQT5Pm93yopDQoJ5B8iZY3i-o6pByjS8uYCvoWZSt8g0IrRW4P3Gw7bgYSOoHDwUWWv5Q4Ra0kRjwQb7NSlsE/s72-c/ChatGPT%20Image%20Apr%205,%202026,%2002_29_25%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-5715822006633499128</guid><pubDate>Sun, 29 Mar 2026 15:48:00 +0000</pubDate><atom:updated>2026-03-29T15:48:08.367+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">csv</category><category domain="http://www.blogger.com/atom/ns#">large files</category><category domain="http://www.blogger.com/atom/ns#">Productivity</category><category domain="http://www.blogger.com/atom/ns#">Python</category><title>Rowlens: finding one exact CSV row in a 17 GB file without blowing up memory</title><description>&lt;p&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh65WHkeBnAjL5weuaCEMa6-79CTBp-mtp460lrmlox5wACR4yRgotXMsSr6HZg_0ygZV3Bge4m-2g6V2PpWw-4eFQ1faVecOEINkSInifyqmelIQgNnqB2v9MdEhkdkTG0YJxHK7VX_lcN0M2O4LEP860qESO1QsWqzTAzZdgGiBjDkF3Iva2wM72CeX4/s1536/ChatGPT%20Image%20Mar%2029,%202026,%2004_47_38%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh65WHkeBnAjL5weuaCEMa6-79CTBp-mtp460lrmlox5wACR4yRgotXMsSr6HZg_0ygZV3Bge4m-2g6V2PpWw-4eFQ1faVecOEINkSInifyqmelIQgNnqB2v9MdEhkdkTG0YJxHK7VX_lcN0M2O4LEP860qESO1QsWqzTAzZdgGiBjDkF3Iva2wM72CeX4/s320/ChatGPT%20Image%20Mar%2029,%202026,%2004_47_38%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Most CSV tooling assumes the file is still small enough to load, sort, or inspect interactively. That breaks down fast once the file is measured in gigabytes.&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;rowlens&lt;/code&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;was built for the opposite case: a CLI you can point at a very large CSV when you already know the clues you are looking for and you want the exact matching rows back in a readable format.&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The design constraint was simple: never read the full file into memory.&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;a href=&quot;https://github.com/JordiCorbilla/rowlens&quot;&gt;rowlens&lt;/a&gt;&lt;/code&gt;&amp;nbsp;opens the CSV as a stream, reads the header once, and then processes each record one at a time with Python&#39;s standard&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;csv&lt;/code&gt;&amp;nbsp;reader. That keeps memory usage effectively flat even when the input file is 17 GB or more. The tool does not build an index, cache rows, or attempt an in-memory dataframe workflow. It just walks the file once and stops early if you set&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--max-results&lt;/code&gt;.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The matching model is intentionally narrow for version 1.0. Repeated&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--keyword&lt;/code&gt;&amp;nbsp;arguments are treated as exact cell-value matches. Repeated&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--filter&lt;/code&gt;&amp;nbsp;arguments are treated as substring checks. A row is returned only when it satisfies every supplied condition. That gives a useful two-stage search pattern in practice: use&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--keyword&lt;/code&gt;&amp;nbsp;for the hard identifier, then&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--filter&lt;/code&gt;&amp;nbsp;to narrow the surrounding context.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Example:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;rowlens --file &lt;span class=&quot;hljs-string&quot;&gt;&quot;huge.csv&quot;&lt;/span&gt; --keyword &lt;span class=&quot;hljs-string&quot;&gt;&quot;1213131&quot;&lt;/span&gt; --filter &lt;span class=&quot;hljs-string&quot;&gt;&quot;AAA&quot;&lt;/span&gt; --output &lt;span class=&quot;hljs-string&quot;&gt;&quot;results.txt&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If a row matches, the output is not dumped as raw CSV. Instead,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;rowlens&lt;/code&gt;&amp;nbsp;renders a bordered CLI report with summary metadata at the top and then a per-match table that lists each column name beside its value. That matters more than it sounds. When you are debugging a production extract or validating a record in an enormous export, the important part is not just finding the row. The important part is understanding the row immediately.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That output style was inspired by terminal-first tooling such as&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;csv-stream-diff&lt;/code&gt;: strong borders, obvious sections, and tabular structure that still works in plain text when redirected to a file. The same rendered report can be written with&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--output&lt;/code&gt;, which makes it easy to attach to a ticket, share in chat, or keep as a trace artifact from an investigation.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Under the hood, Python was a good fit here because the problem is mostly streaming IO plus deterministic row checks. The package is structured with Poetry from the start so it can be shipped cleanly to PyPI. The CLI entry point lives behind the&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;rowlens&lt;/code&gt;&amp;nbsp;console script, dependencies are minimal, and the test suite covers the main behaviors: combined keyword and filter matching, case-insensitive search, support for extra cells beyond the header, and output-file generation.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Version 1.0 is deliberately focused. It solves one job well: find the exact row you care about in a file too large for the usual tools, then present it cleanly. Future iterations could add column-scoped matching, JSON output, compressed input support, or richer summary stats. But the first release already hits the core operational need: streaming search for massive CSVs with output that humans can read immediately.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/03/rowlens-finding-one-exact-csv-row-in-17.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh65WHkeBnAjL5weuaCEMa6-79CTBp-mtp460lrmlox5wACR4yRgotXMsSr6HZg_0ygZV3Bge4m-2g6V2PpWw-4eFQ1faVecOEINkSInifyqmelIQgNnqB2v9MdEhkdkTG0YJxHK7VX_lcN0M2O4LEP860qESO1QsWqzTAzZdgGiBjDkF3Iva2wM72CeX4/s72-c/ChatGPT%20Image%20Mar%2029,%202026,%2004_47_38%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-3076618669400551702</guid><pubDate>Sat, 28 Mar 2026 22:00:00 +0000</pubDate><atom:updated>2026-03-28T22:00:09.637+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">csv</category><category domain="http://www.blogger.com/atom/ns#">exporter</category><category domain="http://www.blogger.com/atom/ns#">Python</category><category domain="http://www.blogger.com/atom/ns#">SQL Server</category><title>Building sqlcsv-exporter: a Python CLI to Stream SQL Server Data into CSV</title><description>&lt;p&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlUQQvA389uHODF4CmfDMdiRASbUCsVe8lLxJIbpR5KZENbaZWk2geoH9uDaR9UMAPv18gPioTmBfBIfOh1ITv0rTYFzIlobRdOdBS87T2MT5p_GgdxwMeV5Qc6QMYnklHDvntq_LNwZN2r2kIFoNsCrkOtJ9fZwb9m-dmh0YsKzsho61dLGdKdTk9DSc/s1536/ChatGPT%20Image%20Mar%2028,%202026,%2009_58_18%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlUQQvA389uHODF4CmfDMdiRASbUCsVe8lLxJIbpR5KZENbaZWk2geoH9uDaR9UMAPv18gPioTmBfBIfOh1ITv0rTYFzIlobRdOdBS87T2MT5p_GgdxwMeV5Qc6QMYnklHDvntq_LNwZN2r2kIFoNsCrkOtJ9fZwb9m-dmh0YsKzsho61dLGdKdTk9DSc/s320/ChatGPT%20Image%20Mar%2028,%202026,%2009_58_18%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;I recently built a small Python package called&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;a href=&quot;https://github.com/JordiCorbilla/sqlcsv-exporter&quot;&gt;sqlcsv-exporter&lt;/a&gt;&lt;/code&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;to solve a very practical problem: export the results of a SQL Server query into a CSV file, from the command line, without dragging an entire dataset into memory.&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The tool is packaged as a Poetry project, designed to be publishable to PyPI, and focused on a workflow that is common in reporting and data operations teams:&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;store the SQL in a&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.sql&lt;/code&gt;&amp;nbsp;file&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;7&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;pass connection details at runtime&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;stream rows in chunks&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;9&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;write the CSV incrementally&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;show visible progress while the job runs&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This post walks through why I built it, how it works, and what I learned while testing it against a local SQL Server instance.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; id=&quot;the-problem&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Problem&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The starting point was familiar: a one-off Python script that connected to SQL Server, ran a query, and wrote a CSV. That works for quick experiments, but it gets messy fast.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Typical issues show up immediately:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;query text is embedded inside Python instead of living in a&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;.sql&lt;/code&gt;&amp;nbsp;file&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;21&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;authentication logic is mixed into export logic&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;22&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the script is hard to reuse across environments&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;large result sets become memory-heavy&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;24&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the UX is poor when a query runs for several seconds or several minutes&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The goal was to replace that with a proper CLI package that feels like a real tool rather than a disposable script.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; id=&quot;the-goal&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Goal&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I wanted a command like this:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;sqlcsv&lt;span class=&quot;hljs-literal&quot;&gt;-exporter&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot;&gt;--sql&lt;/span&gt; .\queries\report.sql `
  &lt;span class=&quot;hljs-literal&quot;&gt;--output&lt;/span&gt; .\exports\report.csv `
  &lt;span class=&quot;hljs-literal&quot;&gt;--server&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;DESKTOP-TTUSQLJ\SQLEXPRESS&quot;&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot;&gt;--database&lt;/span&gt; QuantDevTest
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The requirements were straightforward:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;read SQL from file&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;43&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;connect to SQL Server with trusted auth or SQL auth&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;stream the result set with&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;fetchmany()&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;45&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;write CSV rows incrementally&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;46&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;avoid pandas for the write path&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;47&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;provide useful progress output&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;48&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;keep the package testable and publishable&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot; id=&quot;the-package-structure&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Package Structure&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I split the project into small modules so each concern is isolated:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;cli.py&lt;/code&gt;: argument parsing and process exit behavior&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;config.py&lt;/code&gt;: config model and validation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;connection.py&lt;/code&gt;: ODBC connection string and connection creation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;57&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;sql_rewriter.py&lt;/code&gt;: SQL file loading and optional variable rewriting&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;58&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;exporter.py&lt;/code&gt;: query execution, chunked fetch, CSV writing, and progress rendering&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;60&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That separation matters because it makes the code easier to test. The CSV writer can be tested without a database. The SQL rewriting logic can be tested with simple strings. The export workflow can be tested with mocked connections and cursors.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;62&quot; dir=&quot;auto&quot; id=&quot;why-streaming-matters&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why Streaming Matters&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;64&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The core design choice was to stream results instead of loading everything into memory.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;66&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The exporter:&lt;/p&gt;&lt;ol class=&quot;code-line&quot; data-line=&quot;68&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;68&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;opens the SQL file&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;69&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;optionally rewrites a declared date variable such as&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;@InAsOfDate&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;70&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;executes the query with&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;pyodbc&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;71&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;fetches rows in chunks&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;72&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;writes each chunk directly to a CSV file&lt;/li&gt;&lt;/ol&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;74&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That keeps the memory profile stable even when the result set gets large.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;76&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Instead of doing something like this:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-python&quot; data-line=&quot;78&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;rows = cursor.fetchall()
writer.writerows(rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;83&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;the tool does this conceptually:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-python&quot; data-line=&quot;85&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;True&lt;/span&gt;:
    rows = cursor.fetchmany(chunk_size)
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;not&lt;/span&gt; rows:
        &lt;span class=&quot;hljs-keyword&quot;&gt;break&lt;/span&gt;
    writer.writerows(rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;93&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That small change is the difference between a toy exporter and something you can trust on real datasets.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;95&quot; dir=&quot;auto&quot; id=&quot;a-better-cli-experience&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;A Better CLI Experience&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;97&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Command-line tools that do database work have one recurring UX problem: silence. If a query takes ten seconds, users start wondering whether the command is stuck, blocked, or dead.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;99&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;So the exporter prints:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;101&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;101&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a short run summary before execution&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;102&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;detected column count after the query starts returning metadata&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;103&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a live progress display while rows are written&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;104&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a final completion summary with rows, columns, file size, and elapsed time&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;106&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I used&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;rich&lt;/code&gt;&amp;nbsp;for the terminal output instead of hand-rolled&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;print()&lt;/code&gt;&amp;nbsp;calls. It gives the tool a more deliberate interface without turning it into a full TUI.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;108&quot; dir=&quot;auto&quot; id=&quot;handling-sql-as-a-file&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Handling SQL as a File&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;110&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;One design decision I liked immediately was keeping SQL in a separate file. That brings a few benefits:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;112&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;112&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the query is easier to inspect and review&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;113&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;analysts or DBAs can edit SQL without touching Python code&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;114&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the same CLI can be reused for many exports&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;115&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;long or multi-step SQL scripts remain readable&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;117&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;For example, this simple test query lives in its own file:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-sql&quot; data-line=&quot;119&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;SELECT&lt;/span&gt; TOP (&lt;span class=&quot;hljs-number&quot;&gt;1000&lt;/span&gt;)
    [Id],
    [Stock],
    [LowPrice],
    [MaxPrice],
    [AvgPrice]
&lt;span class=&quot;hljs-keyword&quot;&gt;FROM&lt;/span&gt; [QuantDevTest].[dbo].[StockMetrics];
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;129&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That file can be passed directly to the CLI without changing the Python package at all.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;131&quot; dir=&quot;auto&quot; id=&quot;optional-sql-rewriting&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Optional SQL Rewriting&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;133&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Some teams keep parameter values in SQL scripts using a declared variable like:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-sql&quot; data-line=&quot;135&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;DECLARE&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;@InAsOfDate&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;DATE&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&#39;2026-03-01&#39;&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;139&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;To support that style, the tool includes a lightweight SQL rewriting step. If the variable exists, the CLI can replace its value based on&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;--date&lt;/code&gt;. If the variable does not exist, the SQL runs unchanged.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;141&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This keeps the interface flexible:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;143&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;SQL files can remain mostly static&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;144&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;operators can adjust date-driven exports without manually editing the file&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;146&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It is intentionally narrow in scope. It is not trying to become a generic SQL templating engine.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;148&quot; dir=&quot;auto&quot; id=&quot;a-real-world-bug-caught-by-live-testing&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;A Real-World Bug Caught by Live Testing&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;150&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The first end-to-end run against my local SQL Server instance did not succeed.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;152&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The CLI connected successfully, but then failed with:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-text&quot; data-line=&quot;154&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;AttributeError: &#39;pyodbc.Cursor&#39; object has no attribute &#39;timeout&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;158&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That was useful. The mocked tests passed, but the live run exposed a compatibility assumption in the code. Some&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;pyodbc&lt;/code&gt;&amp;nbsp;environments expose timeout behavior differently.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;160&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The fix was simple:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;162&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;try setting the timeout on the cursor if that attribute exists&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;163&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;otherwise fall back to the connection object&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;165&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is exactly why live testing matters. A tool can look clean in unit tests and still fail in a real environment for reasons that only surface with the actual driver and actual database connection.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;167&quot; dir=&quot;auto&quot; id=&quot;stress-testing-with-a-slower-query&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Stress Testing with a Slower Query&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;169&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;A fast export is not a great demo for progress reporting, so I added a dedicated slow test query.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;171&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;173&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;173&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;copies base rows into a temp table&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;174&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;creates two multiplier temp tables&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;175&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;cross joins them to expand the result set&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;176&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;adds a short&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;WAITFOR DELAY&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;178&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That makes it easy to simulate a longer-running export without needing a large production-sized table.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;180&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Conceptually, the query looks like this:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-sql&quot; data-line=&quot;182&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;SELECT&lt;/span&gt; TOP (&lt;span class=&quot;hljs-number&quot;&gt;1000&lt;/span&gt;) ... &lt;span class=&quot;hljs-keyword&quot;&gt;INTO&lt;/span&gt; #BaseStockMetrics ...
&lt;span class=&quot;hljs-keyword&quot;&gt;SELECT&lt;/span&gt; TOP (&lt;span class=&quot;hljs-number&quot;&gt;200&lt;/span&gt;) ... &lt;span class=&quot;hljs-keyword&quot;&gt;INTO&lt;/span&gt; #MultiplierA ...
&lt;span class=&quot;hljs-keyword&quot;&gt;SELECT&lt;/span&gt; TOP (&lt;span class=&quot;hljs-number&quot;&gt;200&lt;/span&gt;) ... &lt;span class=&quot;hljs-keyword&quot;&gt;INTO&lt;/span&gt; #MultiplierB ...

WAITFOR DELAY &lt;span class=&quot;hljs-string&quot;&gt;&#39;00:00:03&#39;&lt;/span&gt;;

&lt;span class=&quot;hljs-keyword&quot;&gt;SELECT&lt;/span&gt; ...
&lt;span class=&quot;hljs-keyword&quot;&gt;FROM&lt;/span&gt; #BaseStockMetrics &lt;span class=&quot;hljs-keyword&quot;&gt;AS&lt;/span&gt; b
&lt;span class=&quot;hljs-keyword&quot;&gt;CROSS&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;JOIN&lt;/span&gt; #MultiplierA &lt;span class=&quot;hljs-keyword&quot;&gt;AS&lt;/span&gt; a
&lt;span class=&quot;hljs-keyword&quot;&gt;CROSS&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;JOIN&lt;/span&gt; #MultiplierB &lt;span class=&quot;hljs-keyword&quot;&gt;AS&lt;/span&gt; c;
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;195&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;With a small base table, this is enough to create a large CSV and make the progress output visible. With a large base table, it can scale very aggressively, so it is the kind of test query you use carefully.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;197&quot; dir=&quot;auto&quot; id=&quot;testing-strategy&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Testing Strategy&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;199&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The package includes pytest coverage around the parts that are most likely to break:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;201&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;201&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;config validation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;202&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;date resolution&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;203&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;SQL file loading&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;204&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;SQL variable rewriting&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;205&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;connection string generation&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;206&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;CSV writing&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;207&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;mocked end-to-end export behavior&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;209&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That balance is important. Not every code path needs a deep integration test, but the components that define correctness should have coverage.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;211&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The live SQL Server run complements those tests by exercising:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;213&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;213&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the actual ODBC driver&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;214&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the actual SQL Server instance&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;215&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;actual filesystem writes&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;216&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;real CLI behavior&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;218&quot; dir=&quot;auto&quot; id=&quot;packaging-for-pypi&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Packaging for PyPI&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;220&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The project is set up as a Poetry package and versioned as&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;1.0.1&lt;/code&gt;.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;222&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Build artifacts are created with:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;224&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;poetry build
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;228&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That produces:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;230&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;230&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a source distribution&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;231&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a wheel&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;233&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Those are the exact artifacts needed for publishing to PyPI.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;235&quot; dir=&quot;auto&quot; id=&quot;example-usage&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Example Usage&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;237&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Trusted connection:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;239&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;poetry run sqlcsv&lt;span class=&quot;hljs-literal&quot;&gt;-exporter&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot;&gt;--sql&lt;/span&gt; .\queries\stock_metrics_top_1000.sql `
  &lt;span class=&quot;hljs-literal&quot;&gt;--output&lt;/span&gt; .\exports\stock_metrics_top_1000.csv `
  &lt;span class=&quot;hljs-literal&quot;&gt;--server&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;DESKTOP-TTUSQLJ\SQLEXPRESS&quot;&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot;&gt;--database&lt;/span&gt; QuantDevTest
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;247&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;SQL authentication:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-powershell&quot; data-line=&quot;249&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;poetry run sqlcsv&lt;span class=&quot;hljs-literal&quot;&gt;-exporter&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot;&gt;--sql&lt;/span&gt; .\queries\stock_metrics_top_1000.sql `
  &lt;span class=&quot;hljs-literal&quot;&gt;--output&lt;/span&gt; .\exports\stock_metrics_top_1000.csv `
  &lt;span class=&quot;hljs-literal&quot;&gt;--server&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;my-server&quot;&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot;&gt;--database&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Reporting&quot;&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot;&gt;--sql-auth&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot;&gt;--username&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;report_user&quot;&lt;/span&gt; `
  &lt;span class=&quot;hljs-literal&quot;&gt;--password&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;secret&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;260&quot; dir=&quot;auto&quot; id=&quot;final-thoughts&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Final Thoughts&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;262&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This is not a huge project, but it is a useful example of turning a script into a tool.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;264&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The interesting part was not the CSV writing itself. It was the engineering around it:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;266&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;266&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;separating concerns into modules&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;267&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;choosing streaming over eager loading&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;268&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;designing a usable CLI&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;269&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;writing tests around the core behavior&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;270&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;validating the tool against a real SQL Server environment&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;272&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is usually the difference between “something that works on my machine” and “something I would actually hand to another team.”&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;274&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If I extend it further, the next areas I would look at are:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;276&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;276&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;environment-variable support for connection defaults&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;277&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;optional gzip output&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;278&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;row count estimates before execution when possible&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;279&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;better handling for very wide result sets&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;280&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;structured logging for scheduled runs&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;282&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;For now,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;sqlcsv-exporter&lt;/code&gt;&amp;nbsp;does the job it was meant to do: run a SQL Server query from a file and stream the results into CSV in a way that is practical, testable, and ready to package.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/03/building-sqlcsv-exporter-python-cli-to.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlUQQvA389uHODF4CmfDMdiRASbUCsVe8lLxJIbpR5KZENbaZWk2geoH9uDaR9UMAPv18gPioTmBfBIfOh1ITv0rTYFzIlobRdOdBS87T2MT5p_GgdxwMeV5Qc6QMYnklHDvntq_LNwZN2r2kIFoNsCrkOtJ9fZwb9m-dmh0YsKzsho61dLGdKdTk9DSc/s72-c/ChatGPT%20Image%20Mar%2028,%202026,%2009_58_18%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-6634847053541739349</guid><pubDate>Sun, 22 Mar 2026 20:30:25 +0000</pubDate><atom:updated>2026-03-27T18:53:25.924+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">csv</category><category domain="http://www.blogger.com/atom/ns#">diff</category><category domain="http://www.blogger.com/atom/ns#">Python</category><title>Building csv-stream-diff: A Fast, Streaming CSV Comparison Tool for Very Large Files</title><description>&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiZghSoBVzhRlA-BOo-Az9CEfg3bybMp6CB9LbAXCfabBM8IFlfB8ZHm__cRmPlhubeqk_eLVf4cdJir9-nZCZOEJI6_NIsFuBOBS5bCSNo3CiiNZMmvxa4UJHVczhsCFRMnN6mPvM0ONpsUMn8IhECvZPGrUXKWBBU7kK2j2oAqNEter_j4jlHAsr65qM&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiZghSoBVzhRlA-BOo-Az9CEfg3bybMp6CB9LbAXCfabBM8IFlfB8ZHm__cRmPlhubeqk_eLVf4cdJir9-nZCZOEJI6_NIsFuBOBS5bCSNo3CiiNZMmvxa4UJHVczhsCFRMnN6mPvM0ONpsUMn8IhECvZPGrUXKWBBU7kK2j2oAqNEter_j4jlHAsr65qM&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-size: 14px;&quot;&gt;Comparing two CSV files sounds simple until the files are no longer small.&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Once the datasets move into the millions of rows, the usual approaches start to fall apart. Loading both files into memory is expensive. Spreadsheet tools stop being useful. Even many ad hoc scripts become slow, fragile, or impossible to run reliably in production-like environments.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is the problem I wanted to solve with&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;csv-stream-diff&lt;/code&gt;.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; id=&quot;the-problem&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Problem&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;In real systems, CSV comparison is rarely just &quot;diff these two files.&quot;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Usually the job looks more like this:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The files are large enough that a full in-memory load is risky or impossible&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;15&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The key columns on the left and right files do not use the same names&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The comparison should only consider a selected subset of columns&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Duplicate keys may exist and need to be reported clearly&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Sometimes a full comparison is required, but sometimes a statistically useful sample is enough&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;19&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;The output needs to be machine-readable so it can feed downstream validation or remediation workflows&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;21&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I wanted a tool that could handle that cleanly, with minimal dependencies, and still be easy to package and run anywhere.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; id=&quot;what-csv-stream-diff-does&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;csv-stream-diff&lt;/code&gt;&amp;nbsp;Does&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;a href=&quot;https://github.com/JordiCorbilla/csv-stream-diff&quot;&gt;csv-stream-diff&lt;/a&gt;&lt;/code&gt;&amp;nbsp;is a Python CLI tool for comparing very large CSV files using:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;streaming reads&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;hash-based partitioning&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;29&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;multiprocessing&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;YAML-driven configuration&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It produces structured output files for:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;rows only on the left&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;35&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;rows only on the right&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;rows with cell-level differences&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;37&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;duplicate keys&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;summary metadata&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It is designed to be practical rather than clever.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot; id=&quot;the-core-design&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Core Design&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The main design constraint was memory.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;46&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If a tool tries to build a single giant in-memory index for both files, it will eventually hit a limit. So instead of comparing the full files at once,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;csv-stream-diff&lt;/code&gt;&amp;nbsp;uses a two-phase approach.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;48&quot; dir=&quot;auto&quot; id=&quot;1-partition-both-files-into-hashed-buckets&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;1. Partition both files into hashed buckets&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Each row key is normalized and hashed into a bucket. The left and right files are streamed row by row and written into matching bucket files on disk.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That matters because rows with the same normalized key always land in the same bucket. Once that is true, each bucket can be compared independently.&lt;/p&gt;&lt;h3 class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; id=&quot;2-compare-buckets-in-parallel&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 1.25em; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; position: relative;&quot;&gt;2. Compare buckets in parallel&lt;/h3&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;56&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;After partitioning, the tool compares bucket pairs using multiple worker processes. Each worker only needs to index one bucket of the left file at a time, not the entire dataset.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;58&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This keeps memory bounded while still taking advantage of all available CPU cores.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;60&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The result is a design that scales much better for heavy loads than a naïve single-process implementation.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;62&quot; dir=&quot;auto&quot; id=&quot;why-yaml-configuration&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why YAML Configuration&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;64&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I did not want the CLI to become a wall of flags.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;66&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The comparison usually needs several pieces of information:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;68&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;68&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the left and right file paths&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;69&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the left and right key columns&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;70&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;the left and right comparison columns&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;71&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;CSV dialect options&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;72&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;output paths&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;73&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;sampling settings&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;74&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;performance settings&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;76&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is much easier to manage in a YAML file than on the command line.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;78&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The CLI still supports overrides, but the YAML file is the primary contract. That makes runs reproducible and easier to version alongside data validation jobs.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;80&quot; dir=&quot;auto&quot; id=&quot;exact-sampling-for-large-validation-runs&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Exact Sampling for Large Validation Runs&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;82&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Sometimes you do not want to compare every row.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;84&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;For example, if the source files contain tens of millions of records, you may want to run a fast validation pass against an exact random sample of keys before committing to a full comparison.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;86&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;csv-stream-diff&lt;/code&gt;&amp;nbsp;supports that:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;88&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;88&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;sampling.size: 0&lt;/code&gt;&amp;nbsp;means compare everything&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;89&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;sampling.size &amp;gt; 0&lt;/code&gt;&amp;nbsp;means compare an exact random sample of left-side unique keys&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;90&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;sampling.seed&lt;/code&gt;&amp;nbsp;makes the sample reproducible&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;92&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This gives you a useful middle ground between tiny spot checks and full heavy-load comparisons.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;94&quot; dir=&quot;auto&quot; id=&quot;handling-duplicate-keys&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Handling Duplicate Keys&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;96&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Duplicate keys are one of the most annoying edge cases in file comparison work.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;98&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If a key appears multiple times, the comparison becomes ambiguous. Instead of failing silently or hiding the problem, the tool reports duplicate keys explicitly and continues using the first occurrence for the main comparison.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;100&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That behaviour is deliberate:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;102&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;102&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;you get a warning&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;103&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;you get a separate duplicate-key artifact&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;104&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;you still get a usable comparison result&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;106&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This makes the tool better suited for messy real-world data.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;108&quot; dir=&quot;auto&quot; id=&quot;keeping-dependencies-small&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Keeping Dependencies Small&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;110&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I wanted the runtime dependency footprint to stay minimal.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;112&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The tool is built mostly with the Python standard library. The only runtime dependency is&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;PyYAML&lt;/code&gt;, which is used for configuration loading.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;114&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That keeps installation simple and reduces operational friction when the tool needs to run in different environments.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;116&quot; dir=&quot;auto&quot; id=&quot;outputs-that-are-actually-useful&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Outputs That Are Actually Useful&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;118&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;One important goal was to avoid producing a human-only report.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;120&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The tool writes separate output files for each class of result, which makes it easier to automate downstream processing:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;122&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;122&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;only_in_left.csv&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;123&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;only_in_right.csv&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;124&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;differences.csv&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;125&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;duplicate_keys.csv&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;126&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;summary.json&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;128&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;differences.csv&lt;/code&gt;&amp;nbsp;file is especially useful because it reports cell-level differences with both the left and right column names and values.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;130&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That means you can do more than say &quot;this row changed.&quot; You can say exactly how it changed.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;132&quot; dir=&quot;auto&quot; id=&quot;testing-the-tool-properly&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Testing the Tool Properly&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;134&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I also wanted the project to be easy to validate.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;136&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;So the repository includes:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;138&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;138&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;unit tests with&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;pytest&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;139&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;BDD-style acceptance tests with&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;behave&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;140&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;a fixture generator that creates two baseline-identical CSV files and then introduces controlled differences&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;142&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The generator makes it easy to create realistic comparison scenarios involving:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;144&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;144&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;changed values&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;145&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;left-only rows&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;146&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;right-only rows&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;147&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;duplicate keys&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;149&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That is useful both for development and for demonstrating the tool to others.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;151&quot; dir=&quot;auto&quot; id=&quot;a-few-practical-lessons&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;A Few Practical Lessons&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;153&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Building this reinforced a few engineering lessons:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;155&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;155&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;For large-file tooling, streaming and partitioning beat clever in-memory shortcuts&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;156&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Exact sampling is worth implementing properly because it gives a fast validation mode without becoming a toy feature&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;157&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Duplicate handling should be explicit, not implicit&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;158&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Machine-readable outputs matter as much as console output&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;159&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Minimal dependencies make utility tools easier to adopt&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;161&quot; dir=&quot;auto&quot; id=&quot;example-usage&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Example Usage&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;163&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;With a config file in place, the tool is intentionally simple to run:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;165&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;python -m csvstreamdiff.cli --config config.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;169&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;You can also override selected settings from the CLI:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;171&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;python -m csvstreamdiff.cli --config config.yaml --sample-size 100000 --workers 8
&lt;/code&gt;&lt;/pre&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;175&quot; dir=&quot;auto&quot; id=&quot;why-i-built-it&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why I Built It&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;177&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This project came from a practical need: compare large CSV datasets reliably, with clear outputs, and without depending on heavy frameworks or fragile one-off scripts.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;179&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The result is a tool that is meant to be packaged, published, and reused anywhere.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;181&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That was the bar from the start.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;181&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi-UWpU84tI9yoDSNNHULk29CaZ6E8EdS3qNp69LsLP0PNVQqk0Xd9tXOSENa5zJ8zbndRX98VyK_xh2PacjfBLRtva8Z0C-k3qguzi9cP8FeEmRrFM5RRaKQwc2eEMe4kDZGaDOPpJVWr7UR9VOlCFdDi8lKdJSkdsIq4sYJWQJa-5XGLyoKd03azh5t0&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;510&quot; data-original-width=&quot;1136&quot; height=&quot;288&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi-UWpU84tI9yoDSNNHULk29CaZ6E8EdS3qNp69LsLP0PNVQqk0Xd9tXOSENa5zJ8zbndRX98VyK_xh2PacjfBLRtva8Z0C-k3qguzi9cP8FeEmRrFM5RRaKQwc2eEMe4kDZGaDOPpJVWr7UR9VOlCFdDi8lKdJSkdsIq4sYJWQJa-5XGLyoKd03azh5t0=w640-h288&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2 class=&quot;code-line code-active-line&quot; data-line=&quot;183&quot; dir=&quot;auto&quot; id=&quot;closing&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Closing&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;185&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you work with large exports, migration validation, reconciliation jobs, or data quality checks, CSV comparison becomes infrastructure very quickly.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;187&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;csv-stream-diff&lt;/code&gt;&amp;nbsp;is my attempt to make that infrastructure solid:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;189&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;189&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;reproducible&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;190&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;scalable&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;191&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;explicit&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;192&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;easy to automate&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;194&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you want to explore the project, the repository includes the CLI, example configuration, test generator, and packaging setup needed to build and publish it.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/03/building-csv-stream-diff-fast-streaming.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEiZghSoBVzhRlA-BOo-Az9CEfg3bybMp6CB9LbAXCfabBM8IFlfB8ZHm__cRmPlhubeqk_eLVf4cdJir9-nZCZOEJI6_NIsFuBOBS5bCSNo3CiiNZMmvxa4UJHVczhsCFRMnN6mPvM0ONpsUMn8IhECvZPGrUXKWBBU7kK2j2oAqNEter_j4jlHAsr65qM=s72-c" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-1971339674031673041</guid><pubDate>Sun, 15 Mar 2026 12:44:00 +0000</pubDate><atom:updated>2026-03-15T21:31:04.725+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">github</category><category domain="http://www.blogger.com/atom/ns#">Ollama</category><category domain="http://www.blogger.com/atom/ns#">openclaw</category><category domain="http://www.blogger.com/atom/ns#">telegram</category><title>Coding from Telegram: my OpenClaw + Ollama setup</title><description>&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiASW05dU0Rk56B7PU3aTBSHNzeF_BDwT7a157Ke7U7oPwvjslYTkGV7FuYBTL7u9V-hMgvB5GTRERIvB9YZnDG0kTW0oBW7b-HrDtTJVcb1qIKHqWjYpeoVIRd5g_0i9S2xhprxKO-g5KN4xQX7Rkjv5DQGMLVA4KLcZ5L0X2mWwhviS-TkNLY9dIa1k/s1536/ChatGPT%20Image%20Mar%2015,%202026,%2012_08_56%20PM.png&quot; style=&quot;clear: left; display: inline; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1536&quot; data-original-width=&quot;1024&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiASW05dU0Rk56B7PU3aTBSHNzeF_BDwT7a157Ke7U7oPwvjslYTkGV7FuYBTL7u9V-hMgvB5GTRERIvB9YZnDG0kTW0oBW7b-HrDtTJVcb1qIKHqWjYpeoVIRd5g_0i9S2xhprxKO-g5KN4xQX7Rkjv5DQGMLVA4KLcZ5L0X2mWwhviS-TkNLY9dIa1k/s320/ChatGPT%20Image%20Mar%2015,%202026,%2012_08_56%20PM.png&quot; width=&quot;213&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style=&quot;text-align: left;&quot;&gt;I finally got a setup working that feels a bit like the future.&lt;/div&gt;&lt;p data-end=&quot;471&quot; data-start=&quot;446&quot;&gt;I launched OpenClaw with:&lt;/p&gt;&lt;pre class=&quot;overflow-visible! px-0!&quot; data-end=&quot;531&quot; data-start=&quot;473&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-[calc(var(--sticky-padding-top)+9*var(--spacing))]&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-bash&quot;&gt;&lt;i&gt;ollama launch openclaw --model kimi-k2.5:cloud&lt;/i&gt;
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;636&quot; data-start=&quot;533&quot;&gt;and connected it to &lt;b&gt;Telegram&lt;/b&gt;, which means I can now talk to my coding assistant directly from my phone.&lt;/p&gt;&lt;p data-end=&quot;749&quot; data-start=&quot;638&quot;&gt;What makes this especially satisfying is that the whole thing is running on a very inexpensive mini PC at home:&lt;/p&gt;&lt;p data-end=&quot;895&quot; data-start=&quot;751&quot;&gt;&lt;strong data-end=&quot;895&quot; data-start=&quot;751&quot;&gt;Mini PC, 12GB RAM + 128GB ROM, Intel Celeron J4125 (up to 2.7 GHz), Windows 10 Pro, dual Wi-Fi 2.4/5G, Bluetooth 4.2, 4K HD, 2 HDMI + 1 VGA.&lt;/strong&gt;&lt;/p&gt;&lt;p data-end=&quot;1039&quot; data-start=&quot;897&quot;&gt;Nothing exotic. Nothing expensive. Just a small, affordable box quietly sitting there, acting as the bridge between my workspace and my phone.&lt;/p&gt;&lt;p data-end=&quot;1211&quot; data-start=&quot;1041&quot;&gt;That is part of the appeal. This setup feels surprisingly capable for something that costs very little and, beyond the hardware I already own, is effectively free to run.&lt;/p&gt;&lt;p data-end=&quot;1589&quot; data-start=&quot;1213&quot;&gt;The interesting part is not just that it chats back. It has access to my workspace, can help create projects, work with files, and act more like a real development companion than a simple question-answer bot. That changes the experience completely. It stops being something I occasionally open in a browser and starts feeling more like an always-available engineering copilot.&lt;/p&gt;&lt;p data-end=&quot;1656&quot; data-start=&quot;1591&quot;&gt;What I like most is the shift in how and where coding can happen.&lt;/p&gt;&lt;p data-end=&quot;1982&quot; data-start=&quot;1658&quot;&gt;I can be away from my desk, out doing groceries, commuting, or just walking around, and still make progress. I can send a quick message to scaffold an idea, create a project structure, inspect something in the workspace, or prepare the next task before I am back in front of the machine. It turns dead time into useful time.&lt;/p&gt;&lt;p data-end=&quot;2055&quot; data-start=&quot;1984&quot;&gt;That is the part that feels powerful: development becomes more ambient.&lt;/p&gt;&lt;p data-end=&quot;2385&quot; data-start=&quot;2057&quot;&gt;Instead of waiting for the perfect focused block at a desk, I can stay connected to the flow of a project throughout the day. A thought appears, I message it. A small task comes to mind, I delegate it. A project idea starts forming, I capture it immediately. By the time I sit down again, some of the groundwork is already done.&lt;/p&gt;&lt;p data-end=&quot;2728&quot; data-start=&quot;2387&quot;&gt;There is also something elegant about the stack itself. Ollama provides a clean way to launch the model workflow, OpenClaw gives the agent a useful operating surface, and Telegram becomes the lightweight interface that makes it all feel natural. No heavy setup on the phone, no friction, no need to open a laptop just to move a task forward.&lt;/p&gt;&lt;p data-end=&quot;3042&quot; data-start=&quot;2730&quot;&gt;The other thing I genuinely like is how accessible it is. You do not need a powerful workstation, a costly hosted service, or a complex mobile setup. A cheap mini PC, a Telegram account, and the right tooling are enough to build something that feels surprisingly close to a personal remote engineering assistant.&lt;/p&gt;&lt;p data-end=&quot;3255&quot; data-start=&quot;3044&quot;&gt;It is still early, of course, and this kind of workflow needs trust, guardrails, and careful handling when it comes to file access and automation. But even in its current form, it already feels genuinely useful.&lt;/p&gt;&lt;p data-end=&quot;3402&quot; data-start=&quot;3257&quot;&gt;A coding assistant in Telegram sounds like a gimmick until it starts helping you build real things while you are standing in a supermarket queue.&lt;/p&gt;&lt;p data-end=&quot;3492&quot; data-start=&quot;3404&quot;&gt;That is when it stops sounding like a demo and starts feeling like a new way of working.&lt;/p&gt;&lt;p&gt;

















&lt;br /&gt;&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/03/coding-from-telegram-my-openclaw-ollama.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiASW05dU0Rk56B7PU3aTBSHNzeF_BDwT7a157Ke7U7oPwvjslYTkGV7FuYBTL7u9V-hMgvB5GTRERIvB9YZnDG0kTW0oBW7b-HrDtTJVcb1qIKHqWjYpeoVIRd5g_0i9S2xhprxKO-g5KN4xQX7Rkjv5DQGMLVA4KLcZ5L0X2mWwhviS-TkNLY9dIa1k/s72-c/ChatGPT%20Image%20Mar%2015,%202026,%2012_08_56%20PM.png" height="72" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-3790779292704483243</guid><pubDate>Sun, 08 Mar 2026 15:39:00 +0000</pubDate><atom:updated>2026-03-09T19:37:46.205+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">arcade</category><category domain="http://www.blogger.com/atom/ns#">pygame</category><category domain="http://www.blogger.com/atom/ns#">Python</category><title>Tina the Destroyer: Turning Family Photos Into a Playable Arcade Game</title><description>&lt;p&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-size: 14px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiWxpR8M85-Z7rR_RINd8sg8PG-BcvWSRqCeey3NJQ4haZhbjBKrQgezS7wJwXdi1sdsxXkSpOGc0nWBVcUjMXCZYKgUFvrvv08TlfLVLBk2QbFAVGcJDVjeREXoY_5y5DfsxHkNMmyMrBEYHNDHh-3l2U39bMpuvP60474TeAHq-yf2-NNSnh2TDdombc&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiWxpR8M85-Z7rR_RINd8sg8PG-BcvWSRqCeey3NJQ4haZhbjBKrQgezS7wJwXdi1sdsxXkSpOGc0nWBVcUjMXCZYKgUFvrvv08TlfLVLBk2QbFAVGcJDVjeREXoY_5y5DfsxHkNMmyMrBEYHNDHh-3l2U39bMpuvP60474TeAHq-yf2-NNSnh2TDdombc&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;I built a small local arcade game called&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-size: 14px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;strong style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;Tina the Destroyer&lt;/strong&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-size: 14px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span face=&quot;-apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif&quot; style=&quot;font-size: 14px;&quot;&gt;with Python and Pygame.&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;4&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The idea was simple and personal: I took pictures of my daughter, converted them into game-ready pixel sprites, and built a one-screen game around that character. The result is a fast arcade loop where Tina smashes falling rats before they hit the ground.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; id=&quot;the-core-idea&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;&lt;br /&gt;&lt;/h2&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; id=&quot;the-core-idea&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Core Idea&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I wanted a game that was:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;10&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Fast to play&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;11&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Easy to understand&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Personal and fun&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;So I designed a tight gameplay loop:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Move left and right&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Press&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;Space&lt;/code&gt;&amp;nbsp;to perform a ground smash&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Squash rats for points&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;19&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Lose a life when a rat reaches the bottom&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Game over after 3 missed rats&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;22&quot; dir=&quot;auto&quot; id=&quot;from-photos-to-sprites&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;From Photos to Sprites&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;24&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The visual pipeline started with real photos. I cleaned and adapted the character images to work as sprite sheets and exported key poses:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;player_idle.png&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;player_smash.png&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;29&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I also prepared enemy and effect assets:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;31&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;31&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;rat.png&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;rat_squashed.png&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;33&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;impact.png&lt;/code&gt;&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;title.png&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;For audio, I added smash, miss, and looped music effects, with fallback loading so the game still runs if a file is missing.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; id=&quot;building-the-game&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Building the Game&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The game is organized into small modules:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;main.py&lt;/code&gt;&amp;nbsp;entrypoint&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;43&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;game.py&lt;/code&gt;&amp;nbsp;state machine and game loop&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;44&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;entities.py&lt;/code&gt;&amp;nbsp;player, rats, and impact effects&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;45&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;settings.py&lt;/code&gt;&amp;nbsp;tuning values&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;46&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;utils.py&lt;/code&gt;&amp;nbsp;asset loading and fallbacks&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;48&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Key features I focused on:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;50&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Clean state flow (&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;TITLE&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;PLAYING&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;GAME_OVER&lt;/code&gt;,&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;QUITTING&lt;/code&gt;)&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;51&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Responsive movement and smash timing&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;52&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Difficulty scaling over time&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;53&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Score/lives HUD&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;54&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Best-score persistence to JSON&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;55&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Graceful fallback behavior for missing assets&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;57&quot; dir=&quot;auto&quot; id=&quot;vibe-coding-the-project&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Vibe Coding the Project&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;I vibe coded this with&amp;nbsp;&lt;strong&gt;gpt-5-3.codex&lt;/strong&gt;, iterating quickly on gameplay feel, tuning values, and production details (asset fallbacks, restart flow, audio handling, and UI polish).&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;59&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Source code:&amp;nbsp;&lt;a href=&quot;https://github.com/JordiCorbilla/tina-the-destroyer&quot;&gt;JordiCorbilla/tina-the-destroyer: tina-the-destroyer&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;61&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;That pairing made it easy to keep momentum: prototype fast, test, adjust, repeat.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;63&quot; dir=&quot;auto&quot; id=&quot;why-i-loved-this-build&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why I Loved This Build&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;65&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This project sits at the intersection of family creativity and engineering. It started as a fun idea with photos and ended up as a fully playable local arcade game I can run anytime with:&lt;/p&gt;&lt;pre style=&quot;background-color: rgba(10, 10, 10, 0.4); border-color: rgb(48, 48, 49); border-image: none 100% / 1 / 0 stretch; border-radius: 3px; border-style: solid; border-width: 1px; font-size: 14px; margin-top: 0px; overflow: auto; padding: 16px; text-wrap-mode: wrap;&quot;&gt;&lt;code class=&quot;code-line language-bash&quot; data-line=&quot;67&quot; dir=&quot;auto&quot; style=&quot;background: none; border-radius: 4px; display: inline-block; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 0px; position: relative; tab-size: 4;&quot;&gt;pip install pygame
python main.py
&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;72&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Small scope, real personality, and a complete game loop. Exactly the kind of build I enjoy.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/03/tina-destroyer-turning-family-photos.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEiWxpR8M85-Z7rR_RINd8sg8PG-BcvWSRqCeey3NJQ4haZhbjBKrQgezS7wJwXdi1sdsxXkSpOGc0nWBVcUjMXCZYKgUFvrvv08TlfLVLBk2QbFAVGcJDVjeREXoY_5y5DfsxHkNMmyMrBEYHNDHh-3l2U39bMpuvP60474TeAHq-yf2-NNSnh2TDdombc=s72-c" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>London, UK</georss:featurename><georss:point>51.5072178 -0.1275862</georss:point><georss:box>23.196983963821154 -35.2838362 79.817451636178845 35.0286638</georss:box></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-6132393536646830344</guid><pubDate>Sun, 15 Feb 2026 21:09:00 +0000</pubDate><atom:updated>2026-03-15T21:35:19.084+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net 9</category><category domain="http://www.blogger.com/atom/ns#">CLI</category><category domain="http://www.blogger.com/atom/ns#">spectre.console</category><category domain="http://www.blogger.com/atom/ns#">vibe coding</category><title>Building a Portfolio CLI in 2026 (and Why CLIs Feel Cool Again)</title><description>&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px;&quot;&gt;Over a single weekend, I decided to build a portfolio tracker that lives entirely in the terminal. Not a web app. Not a spreadsheet. A real, interactive CLI with panels, charts, and daily tracking.&lt;/span&gt;&lt;/div&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;2&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgasgqBfoOzXHRnLxyRi7lG_Mo-SBXednHuueBekIGEqwKjbAHk5eGauvXYbwv6QU47HatMtlit6cz-2qACJUL4bKPoiT2Ilih2su0WeLWUux8yCTb_xKAALbPwAQt0ehRJ9KnPDWJ-m-uw8Lkh7UoLa8diDQp2rzJdazRzwRU_xe1STcJuRleY6sXGm8w&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;968&quot; data-original-width=&quot;1896&quot; height=&quot;326&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgasgqBfoOzXHRnLxyRi7lG_Mo-SBXednHuueBekIGEqwKjbAHk5eGauvXYbwv6QU47HatMtlit6cz-2qACJUL4bKPoiT2Ilih2su0WeLWUux8yCTb_xKAALbPwAQt0ehRJ9KnPDWJ-m-uw8Lkh7UoLa8diDQp2rzJdazRzwRU_xe1STcJuRleY6sXGm8w=w640-h326&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I also wanted it to fit how I actually work: Excel as the source of truth, but with a console experience that makes daily updates fast and visual.&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;6&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This was vibe-coded with Chat GPT-5-2-Codex over a weekend, which made it surprisingly fun to iterate on UI tweaks, edge cases, and the overall feel.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;8&quot; dir=&quot;auto&quot; id=&quot;why-a-cli&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Why a CLI?&lt;/h2&gt;&lt;p class=&quot;code-line code-active-line&quot; data-line=&quot;9&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;CLIs are back. Not because they&#39;re nostalgic, but because they&#39;re fast, distraction-free, and feel like tools instead of products. A good CLI lets you focus on the data and decisions rather than the UI chrome.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;11&quot; dir=&quot;auto&quot; id=&quot;what-i-built&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What I Built&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;12&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The result is&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;&lt;a href=&quot;https://github.com/JordiCorbilla/my-portfolio-cli&quot;&gt;my-portfolio-cli&lt;/a&gt;&lt;/code&gt;, an interactive portfolio dashboard that:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;13&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;13&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Reads data from an Excel workbook.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;14&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Renders a rich TUI with Spectre.Console.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;15&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Shows daily PnL, MTD performance, and FY summaries.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;16&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Displays a simple PnL bar chart right in the terminal.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;17&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Lets you add a new daily snapshot instantly.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;18&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Creates new monthly sheets when you need them.&lt;/li&gt;&lt;/ul&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;20&quot; dir=&quot;auto&quot; id=&quot;the-flow&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;The Flow&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;21&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;Start it and it opens directly in interactive mode. Use arrow keys to move across days and months. Press&amp;nbsp;&lt;code style=&quot;background-color: rgba(255, 255, 255, 0.1); border-radius: 4px; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 1em; line-height: 1.357em; padding: 1px 3px;&quot;&gt;A&lt;/code&gt;&amp;nbsp;to add a new entry. If the month doesn&#39;t exist yet, it creates it automatically.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;23&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you&#39;re starting from scratch (no workbook or no month sheets), the CLI prompts you to create the first month, add accounts, and enter initial values.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;25&quot; dir=&quot;auto&quot; id=&quot;design-notes&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;Design Notes&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;26&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;The key was making it feel like a real console app:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;27&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Clean layout with strong visual hierarchy.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;28&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Color-coded gains and losses.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;29&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;A compact FY summary that&#39;s readable at a glance.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;30&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;A minimal bar chart for quick trend cues.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;32&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;It isn&#39;t about being fancy. It&#39;s about being useful and enjoyable to use every day.&lt;/p&gt;&lt;h2 class=&quot;code-line&quot; data-line=&quot;34&quot; dir=&quot;auto&quot; id=&quot;whats-next&quot; style=&quot;border-bottom: 1px solid rgba(255, 255, 255, 0.18); border-left-color: rgba(255, 255, 255, 0.18); border-right-color: rgba(255, 255, 255, 0.18); border-top-color: rgba(255, 255, 255, 0.18); font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; line-height: 1.25; margin-bottom: 16px; margin-top: 24px; padding-bottom: 0.3em; position: relative;&quot;&gt;What&#39;s Next&lt;/h2&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;35&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;This project is going online soon, which means:&lt;/p&gt;&lt;ul class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 0.7em; margin-top: 0px; position: relative;&quot;&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;36&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;A demo workbook and screenshots.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;37&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;A short walkthrough.&lt;/li&gt;&lt;li class=&quot;code-line&quot; data-line=&quot;38&quot; dir=&quot;auto&quot; style=&quot;position: relative;&quot;&gt;Possibly a minimal installer or single-file publish.&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;40&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;For now, it&#39;s a tight little tool that does exactly what I need.&lt;/p&gt;&lt;p class=&quot;code-line&quot; data-line=&quot;42&quot; dir=&quot;auto&quot; style=&quot;font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe WPC&amp;quot;, &amp;quot;Segoe UI&amp;quot;, system-ui, Ubuntu, &amp;quot;Droid Sans&amp;quot;, sans-serif; font-size: 14px; margin-bottom: 16px; margin-top: 0px; position: relative;&quot;&gt;If you want to build your own CLI tool, I highly recommend it. The feedback loop is short, and it&#39;s easy to keep refining the experience until it feels right.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/02/building-portfolio-cli-in-2026-and-why.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEgasgqBfoOzXHRnLxyRi7lG_Mo-SBXednHuueBekIGEqwKjbAHk5eGauvXYbwv6QU47HatMtlit6cz-2qACJUL4bKPoiT2Ilih2su0WeLWUux8yCTb_xKAALbPwAQt0ehRJ9KnPDWJ-m-uw8Lkh7UoLa8diDQp2rzJdazRzwRU_xe1STcJuRleY6sXGm8w=s72-w640-h326-c" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-7888794576508862265</guid><pubDate>Sun, 25 Jan 2026 17:37:00 +0000</pubDate><atom:updated>2026-01-25T17:37:53.845+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AI Coding Agents</category><category domain="http://www.blogger.com/atom/ns#">Claude Code</category><category domain="http://www.blogger.com/atom/ns#">Developer Tooling</category><category domain="http://www.blogger.com/atom/ns#">Local LLM</category><category domain="http://www.blogger.com/atom/ns#">Offline AI</category><category domain="http://www.blogger.com/atom/ns#">Ollama</category><category domain="http://www.blogger.com/atom/ns#">Private AI</category><category domain="http://www.blogger.com/atom/ns#">VS Code</category><title>Running Claude Code Fully Locally with Ollama (Yes, It’s Possible — With Caveats)</title><description>&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9WeixbvB2oF-WOzD69_uFgmOsJ0xiUFPaV5rjs39NGGc1-0axBdzGYBQBpMNL3Nh4SXifIJOZCaYeja16D9YLWvRXk2xRfrtx0FNWIIZCx9dMgZatSXY7BiFPUz0z9gZpI-YhgNfgLbjqisB6y6ZUW1qnNjyywe5KZTvYWjzFPFKEE-xK5td5rAaYh-Q/s1536/ChatGPT%20Image%20Jan%2025,%202026,%2005_20_49%20PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1536&quot; height=&quot;213&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9WeixbvB2oF-WOzD69_uFgmOsJ0xiUFPaV5rjs39NGGc1-0axBdzGYBQBpMNL3Nh4SXifIJOZCaYeja16D9YLWvRXk2xRfrtx0FNWIIZCx9dMgZatSXY7BiFPUz0z9gZpI-YhgNfgLbjqisB6y6ZUW1qnNjyywe5KZTvYWjzFPFKEE-xK5td5rAaYh-Q/s320/ChatGPT%20Image%20Jan%2025,%202026,%2005_20_49%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Claude Code is designed as a &lt;strong data-end=&quot;448&quot; data-start=&quot;406&quot;&gt;cloud-first, tool-centric coding agent&lt;/strong&gt; tightly coupled to Anthropic’s infrastructure. Out of the box, it &lt;strong data-end=&quot;548&quot; data-start=&quot;515&quot;&gt;does not support local models&lt;/strong&gt;.&lt;p&gt;&lt;/p&gt;
&lt;p data-end=&quot;582&quot; data-start=&quot;551&quot;&gt;However, with a combination of:&lt;/p&gt;
&lt;ul data-end=&quot;672&quot; data-start=&quot;583&quot;&gt;
&lt;li data-end=&quot;606&quot; data-start=&quot;583&quot;&gt;
&lt;p data-end=&quot;606&quot; data-start=&quot;585&quot;&gt;endpoint redirection,&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;638&quot; data-start=&quot;607&quot;&gt;
&lt;p data-end=&quot;638&quot; data-start=&quot;609&quot;&gt;model aliasing inside Ollama,&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;672&quot; data-start=&quot;639&quot;&gt;
&lt;p data-end=&quot;672&quot; data-start=&quot;641&quot;&gt;and a tool-capable local model,&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;791&quot; data-start=&quot;674&quot;&gt;you &lt;em data-end=&quot;683&quot; data-start=&quot;678&quot;&gt;can&lt;/em&gt; run Claude Code &lt;strong data-end=&quot;720&quot; data-start=&quot;700&quot;&gt;entirely locally&lt;/strong&gt; against Ollama — including &lt;strong data-end=&quot;790&quot; data-start=&quot;748&quot;&gt;file edits, refactors, and shell tools&lt;/strong&gt;.&lt;/p&gt;
&lt;p data-end=&quot;918&quot; data-start=&quot;793&quot;&gt;This article documents the &lt;strong data-end=&quot;845&quot; data-start=&quot;820&quot;&gt;exact path that works&lt;/strong&gt;, the &lt;strong data-end=&quot;881&quot; data-start=&quot;851&quot;&gt;failure modes you will hit&lt;/strong&gt;, and the &lt;strong data-end=&quot;917&quot; data-start=&quot;891&quot;&gt;engineering trade-offs&lt;/strong&gt;.&lt;/p&gt;&lt;h2 data-end=&quot;966&quot; data-start=&quot;925&quot;&gt;Why Claude Code Is Hard to Run Locally&lt;/h2&gt;&lt;p data-end=&quot;1011&quot; data-start=&quot;968&quot;&gt;Claude Code makes three strong assumptions:&lt;/p&gt;&lt;ol data-end=&quot;1146&quot; data-start=&quot;1013&quot;&gt;
&lt;li data-end=&quot;1064&quot; data-start=&quot;1013&quot;&gt;
&lt;p data-end=&quot;1064&quot; data-start=&quot;1016&quot;&gt;&lt;strong data-end=&quot;1064&quot; data-start=&quot;1016&quot;&gt;Anthropic authentication is always available&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1113&quot; data-start=&quot;1065&quot;&gt;
&lt;p data-end=&quot;1113&quot; data-start=&quot;1068&quot;&gt;&lt;strong data-end=&quot;1093&quot; data-start=&quot;1068&quot;&gt;Model names are fixed&lt;/strong&gt; (&lt;code data-end=&quot;1112&quot; data-start=&quot;1095&quot;&gt;claude-sonnet-*&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1146&quot; data-start=&quot;1114&quot;&gt;
&lt;p data-end=&quot;1146&quot; data-start=&quot;1117&quot;&gt;&lt;strong data-end=&quot;1146&quot; data-start=&quot;1117&quot;&gt;Tool calling is mandatory&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p data-end=&quot;1221&quot; data-start=&quot;1148&quot;&gt;Most “local Claude” guides fail because they only solve &lt;strong data-end=&quot;1211&quot; data-start=&quot;1204&quot;&gt;one&lt;/strong&gt; of these.&lt;/p&gt;&lt;p data-end=&quot;1264&quot; data-start=&quot;1223&quot;&gt;To succeed, you must solve &lt;strong data-end=&quot;1263&quot; data-start=&quot;1250&quot;&gt;all three&lt;/strong&gt;.&lt;/p&gt;&lt;hr data-end=&quot;1269&quot; data-start=&quot;1266&quot; /&gt;&lt;h2 data-end=&quot;1306&quot; data-start=&quot;1271&quot;&gt;Architecture That Actually Works&lt;/h2&gt;&lt;pre class=&quot;overflow-visible! px-0!&quot; data-end=&quot;1539&quot; data-start=&quot;1308&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl/main:top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre!&quot;&gt;VS &lt;span class=&quot;hljs-selector-tag&quot;&gt;Code&lt;/span&gt;
 └─ Claude &lt;span class=&quot;hljs-selector-tag&quot;&gt;Code&lt;/span&gt; extension
     ├─ hardcoded model name (claude-sonnet-*)
     ├─ mandatory tools
     └─ Anthropic-style requests
           ↓
      Ollama (localhost)
           ↓
   Tool-capable local model (Qwen)
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;1555&quot; data-start=&quot;1541&quot;&gt;Key insight:&lt;/p&gt;&lt;p data-end=&quot;918&quot; data-start=&quot;793&quot;&gt;








&lt;/p&gt;&lt;blockquote data-end=&quot;1633&quot; data-start=&quot;1556&quot;&gt;
&lt;p data-end=&quot;1633&quot; data-start=&quot;1558&quot;&gt;You don’t change Claude Code — you &lt;strong data-end=&quot;1632&quot; data-start=&quot;1593&quot;&gt;adapt Ollama to look like Anthropic&lt;/strong&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 data-end=&quot;1681&quot; data-start=&quot;1640&quot;&gt;Step 1: Redirect Claude Code to Ollama&lt;/h2&gt;&lt;p data-end=&quot;1710&quot; data-start=&quot;1683&quot;&gt;In VS Code &lt;code data-end=&quot;1709&quot; data-start=&quot;1694&quot;&gt;Command palette -&amp;gt; Preferences: Open User Settings (JSON)&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&quot;overflow-visible! px-0!&quot; data-end=&quot;1974&quot; data-start=&quot;1712&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl/main:top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-json&quot;&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;claudeCode.environmentVariables&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;ANTHROPIC_BASE_URL&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;http://127.0.0.1:11434&quot;&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;ANTHROPIC_AUTH_TOKEN&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;ollama&quot;&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;claudeCode.disableLoginPrompt&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;2038&quot; data-start=&quot;1976&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgJBceCONKj-YQIyfSWW2Soc2jhAUO3v7HNCC868hhWA6Wc3baPSU9y8WNMtK456kkMIp8gUXzJ5ME87WBujBtdUt2mMqVcixMr8GWdteFPR2cEjSTvgruZxRl2rdsIoGxuI7Vhqf_NYezIidHLdslbGtlmVW_Re2U9Bh7y3V3GErCQaf9CchF8jOMbSsE&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;326&quot; data-original-width=&quot;666&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgJBceCONKj-YQIyfSWW2Soc2jhAUO3v7HNCC868hhWA6Wc3baPSU9y8WNMtK456kkMIp8gUXzJ5ME87WBujBtdUt2mMqVcixMr8GWdteFPR2cEjSTvgruZxRl2rdsIoGxuI7Vhqf_NYezIidHLdslbGtlmVW_Re2U9Bh7y3V3GErCQaf9CchF8jOMbSsE=s16000&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p data-end=&quot;2038&quot; data-start=&quot;1976&quot;&gt;This bypasses cloud calls and sends &lt;strong data-end=&quot;2037&quot; data-start=&quot;2012&quot;&gt;all traffic to Ollama&lt;/strong&gt;.&lt;/p&gt;&lt;p data-end=&quot;2054&quot; data-start=&quot;2040&quot;&gt;At this point:&lt;/p&gt;&lt;ul data-end=&quot;2124&quot; data-start=&quot;2055&quot;&gt;
&lt;li data-end=&quot;2065&quot; data-start=&quot;2055&quot;&gt;
&lt;p data-end=&quot;2065&quot; data-start=&quot;2057&quot;&gt;UI works&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2081&quot; data-start=&quot;2066&quot;&gt;
&lt;p data-end=&quot;2081&quot; data-start=&quot;2068&quot;&gt;Requests flow&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2124&quot; data-start=&quot;2082&quot;&gt;
&lt;p data-end=&quot;2124&quot; data-start=&quot;2084&quot;&gt;But you will get &lt;strong data-end=&quot;2124&quot; data-start=&quot;2101&quot;&gt;404 model not found&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p data-end=&quot;918&quot; data-start=&quot;793&quot;&gt;





&lt;/p&gt;&lt;p data-end=&quot;2143&quot; data-start=&quot;2126&quot;&gt;That is expected.&lt;/p&gt;&lt;h2 data-end=&quot;2194&quot; data-start=&quot;2150&quot;&gt;Step 2: Understand the Model Name Problem&lt;/h2&gt;&lt;p data-end=&quot;2242&quot; data-start=&quot;2196&quot;&gt;Claude Code &lt;strong data-end=&quot;2218&quot; data-start=&quot;2208&quot;&gt;always&lt;/strong&gt; sends model names like:&lt;/p&gt;&lt;pre class=&quot;overflow-visible! px-0!&quot; data-end=&quot;2278&quot; data-start=&quot;2244&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl/main:top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre!&quot;&gt;claude-sonnet-4-5-20250929
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;2317&quot; data-start=&quot;2280&quot;&gt;Ollama does &lt;strong data-end=&quot;2299&quot; data-start=&quot;2292&quot;&gt;not&lt;/strong&gt; have such models.&lt;/p&gt;&lt;p data-end=&quot;2396&quot; data-start=&quot;2319&quot;&gt;You cannot configure Claude Code to use &lt;code data-end=&quot;2366&quot; data-start=&quot;2359&quot;&gt;gemma&lt;/code&gt;, &lt;code data-end=&quot;2375&quot; data-start=&quot;2368&quot;&gt;llama&lt;/code&gt;, or &lt;code data-end=&quot;2386&quot; data-start=&quot;2380&quot;&gt;qwen&lt;/code&gt; directly.&lt;/p&gt;&lt;h3 data-end=&quot;2426&quot; data-start=&quot;2398&quot;&gt;Solution: Model aliasing&lt;/h3&gt;&lt;p data-end=&quot;2510&quot; data-start=&quot;2428&quot;&gt;Ollama lets you create &lt;strong data-end=&quot;2474&quot; data-start=&quot;2451&quot;&gt;lightweight aliases&lt;/strong&gt; that map one model name to another.&lt;/p&gt;&lt;hr data-end=&quot;2515&quot; data-start=&quot;2512&quot; /&gt;&lt;h2 data-end=&quot;2555&quot; data-start=&quot;2517&quot;&gt;Step 3: Why Gemma Fails (Important)&lt;/h2&gt;&lt;p data-end=&quot;2624&quot; data-start=&quot;2557&quot;&gt;Gemma models (including &lt;code data-end=&quot;2590&quot; data-start=&quot;2581&quot;&gt;gemma3n&lt;/code&gt;) &lt;strong data-end=&quot;2623&quot; data-start=&quot;2592&quot;&gt;do not support tool calling&lt;/strong&gt;.&lt;/p&gt;&lt;p data-end=&quot;2670&quot; data-start=&quot;2626&quot;&gt;Claude Code &lt;em data-end=&quot;2646&quot; data-start=&quot;2638&quot;&gt;always&lt;/em&gt; sends a &lt;code data-end=&quot;2662&quot; data-start=&quot;2655&quot;&gt;tools&lt;/code&gt; schema.&lt;/p&gt;&lt;p data-end=&quot;2688&quot; data-start=&quot;2672&quot;&gt;Resulting error:&lt;/p&gt;&lt;pre class=&quot;overflow-visible! px-0!&quot; data-end=&quot;2720&quot; data-start=&quot;2690&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl/main:top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre!&quot;&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;does&lt;/span&gt; not support tools
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;2780&quot; data-start=&quot;2722&quot;&gt;This is a &lt;strong data-end=&quot;2748&quot; data-start=&quot;2732&quot;&gt;hard failure&lt;/strong&gt;, not a timeout or config issue.&lt;/p&gt;&lt;h3 data-end=&quot;2796&quot; data-start=&quot;2782&quot;&gt;Conclusion&lt;/h3&gt;&lt;blockquote data-end=&quot;2846&quot; data-start=&quot;2798&quot;&gt;
&lt;p data-end=&quot;2846&quot; data-start=&quot;2800&quot;&gt;Gemma works for chat, &lt;strong data-end=&quot;2829&quot; data-start=&quot;2822&quot;&gt;not&lt;/strong&gt; for Claude Code.&lt;/p&gt;
&lt;/blockquote&gt;&lt;hr data-end=&quot;2851&quot; data-start=&quot;2848&quot; /&gt;&lt;h2 data-end=&quot;2888&quot; data-start=&quot;2853&quot;&gt;Step 4: Use a Tool-Capable Model&lt;/h2&gt;&lt;p data-end=&quot;2921&quot; data-start=&quot;2890&quot;&gt;You need a model that supports:&lt;/p&gt;&lt;ul data-end=&quot;2982&quot; data-start=&quot;2922&quot;&gt;
&lt;li data-end=&quot;2945&quot; data-start=&quot;2922&quot;&gt;
&lt;p data-end=&quot;2945&quot; data-start=&quot;2924&quot;&gt;structured tool calls&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2962&quot; data-start=&quot;2946&quot;&gt;
&lt;p data-end=&quot;2962&quot; data-start=&quot;2948&quot;&gt;JSON responses&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2982&quot; data-start=&quot;2963&quot;&gt;
&lt;p data-end=&quot;2982&quot; data-start=&quot;2965&quot;&gt;streaming + edits&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;h3 data-end=&quot;2999&quot; data-start=&quot;2984&quot;&gt;Recommended&lt;/h3&gt;&lt;pre class=&quot;overflow-visible! px-0!&quot; data-end=&quot;3041&quot; data-start=&quot;3001&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl/main:top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-bash&quot;&gt;ollama pull qwen2.5-coder:7b
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;3111&quot; data-start=&quot;3043&quot;&gt;This is the &lt;strong data-end=&quot;3082&quot; data-start=&quot;3055&quot;&gt;smallest reliable model&lt;/strong&gt; that works with Claude Code.&lt;/p&gt;&lt;hr data-end=&quot;3116&quot; data-start=&quot;3113&quot; /&gt;&lt;h2 data-end=&quot;3161&quot; data-start=&quot;3118&quot;&gt;Step 5: Create Claude-Compatible Aliases&lt;/h2&gt;&lt;p data-end=&quot;3184&quot; data-start=&quot;3163&quot;&gt;Create a &lt;code data-end=&quot;3183&quot; data-start=&quot;3172&quot;&gt;Modelfile&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&quot;overflow-visible! px-0!&quot; data-end=&quot;3215&quot; data-start=&quot;3186&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl/main:top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre!&quot;&gt;&lt;span class=&quot;hljs-selector-tag&quot;&gt;FROM&lt;/span&gt; qwen2.&lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;-coder:&lt;span class=&quot;hljs-number&quot;&gt;7&lt;/span&gt;b
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;3257&quot; data-start=&quot;3217&quot;&gt;Then create aliases Claude Code expects:&lt;/p&gt;&lt;pre class=&quot;overflow-visible! px-0!&quot; data-end=&quot;3393&quot; data-start=&quot;3259&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl/main:top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-bash&quot;&gt;ollama create claude-sonnet -f Modelfile
ollama create claude-opus   -f Modelfile
ollama create claude-haiku  -f Modelfile
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;3449&quot; data-start=&quot;3395&quot;&gt;No weights are duplicated.&lt;br data-end=&quot;3424&quot; data-start=&quot;3421&quot; /&gt;
Only metadata is created.&lt;/p&gt;&lt;p data-end=&quot;2143&quot; data-start=&quot;2126&quot;&gt;





























&lt;/p&gt;&lt;p data-end=&quot;3504&quot; data-start=&quot;3451&quot;&gt;Now Ollama can answer requests for &lt;code data-end=&quot;3503&quot; data-start=&quot;3486&quot;&gt;claude-sonnet-*&lt;/code&gt;.&lt;/p&gt;&lt;h2 data-end=&quot;3991&quot; data-start=&quot;3957&quot;&gt;Result: Fully Local Claude Code&lt;/h2&gt;&lt;p data-end=&quot;4024&quot; data-start=&quot;3993&quot;&gt;At this point, Claude Code can:&lt;/p&gt;&lt;ul data-end=&quot;4111&quot; data-start=&quot;4026&quot;&gt;
&lt;li data-end=&quot;4040&quot; data-start=&quot;4026&quot;&gt;
&lt;p data-end=&quot;4040&quot; data-start=&quot;4028&quot;&gt;create files&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4053&quot; data-start=&quot;4041&quot;&gt;
&lt;p data-end=&quot;4053&quot; data-start=&quot;4043&quot;&gt;edit files&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4074&quot; data-start=&quot;4054&quot;&gt;
&lt;p data-end=&quot;4074&quot; data-start=&quot;4056&quot;&gt;run shell commands&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4090&quot; data-start=&quot;4075&quot;&gt;
&lt;p data-end=&quot;4090&quot; data-start=&quot;4077&quot;&gt;refactor code&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4111&quot; data-start=&quot;4091&quot;&gt;
&lt;p data-end=&quot;4111&quot; data-start=&quot;4093&quot;&gt;reason about repos&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p data-end=&quot;3504&quot; data-start=&quot;3451&quot;&gt;


&lt;/p&gt;&lt;p data-end=&quot;4142&quot; data-start=&quot;4113&quot;&gt;All &lt;strong data-end=&quot;4141&quot; data-start=&quot;4117&quot;&gt;without cloud access&lt;/strong&gt;.&lt;/p&gt;&lt;p data-end=&quot;4142&quot; data-start=&quot;4113&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiSfEZPwYWlCqJEwYENT6QW5PD-Bv7Xhw91DcI0yCsJNILt9NSwUeISmRhLRn945hhJl0MifA1eZ1LncwuiI3jODNdg5hRYKwp4Iqc6h-Pwnm8EcH2uHTfneP-tjCSeKpv7iPRTy96DapQ6tjwKI3HTF4krOl6d98EJb2bclRc1M9LkyqK_ra-Rge9ab5o&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;880&quot; data-original-width=&quot;1437&quot; height=&quot;392&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiSfEZPwYWlCqJEwYENT6QW5PD-Bv7Xhw91DcI0yCsJNILt9NSwUeISmRhLRn945hhJl0MifA1eZ1LncwuiI3jODNdg5hRYKwp4Iqc6h-Pwnm8EcH2uHTfneP-tjCSeKpv7iPRTy96DapQ6tjwKI3HTF4krOl6d98EJb2bclRc1M9LkyqK_ra-Rge9ab5o=w640-h392&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgy8YSIlu5-MQgrqg-0s4_CMnLFkCWs3pDxIK_eGSc24exhoiYBN94Xrp4nw2-eWfKxEavd_mig2wOqwybj9o22BNb5UkGmEZdgB6jR2s3E5S-pZegxeFv7wrW4lKJQNHvJugD77bCUOZGtDcsGOdjhK8gMjZtxVNQJWzfwBaHzJsmFh7DZnqv0JNVx-MY&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;991&quot; data-original-width=&quot;1902&quot; height=&quot;334&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgy8YSIlu5-MQgrqg-0s4_CMnLFkCWs3pDxIK_eGSc24exhoiYBN94Xrp4nw2-eWfKxEavd_mig2wOqwybj9o22BNb5UkGmEZdgB6jR2s3E5S-pZegxeFv7wrW4lKJQNHvJugD77bCUOZGtDcsGOdjhK8gMjZtxVNQJWzfwBaHzJsmFh7DZnqv0JNVx-MY=w640-h334&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2026/01/running-claude-code-fully-locally-with.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9WeixbvB2oF-WOzD69_uFgmOsJ0xiUFPaV5rjs39NGGc1-0axBdzGYBQBpMNL3Nh4SXifIJOZCaYeja16D9YLWvRXk2xRfrtx0FNWIIZCx9dMgZatSXY7BiFPUz0z9gZpI-YhgNfgLbjqisB6y6ZUW1qnNjyywe5KZTvYWjzFPFKEE-xK5td5rAaYh-Q/s72-c/ChatGPT%20Image%20Jan%2025,%202026,%2005_20_49%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-6190973653015376234</guid><pubDate>Sun, 12 Oct 2025 19:23:00 +0000</pubDate><atom:updated>2026-03-15T21:35:57.801+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AG2</category><category domain="http://www.blogger.com/atom/ns#">AI</category><category domain="http://www.blogger.com/atom/ns#">asset allocation</category><category domain="http://www.blogger.com/atom/ns#">AutoGen</category><category domain="http://www.blogger.com/atom/ns#">budgeting</category><category domain="http://www.blogger.com/atom/ns#">Chainlit</category><category domain="http://www.blogger.com/atom/ns#">ChatBot</category><category domain="http://www.blogger.com/atom/ns#">compliance</category><category domain="http://www.blogger.com/atom/ns#">Finance</category><category domain="http://www.blogger.com/atom/ns#">group chat</category><category domain="http://www.blogger.com/atom/ns#">Investment</category><category domain="http://www.blogger.com/atom/ns#">llm</category><category domain="http://www.blogger.com/atom/ns#">macroeconomics</category><category domain="http://www.blogger.com/atom/ns#">market analysis</category><category domain="http://www.blogger.com/atom/ns#">multi-agent</category><category domain="http://www.blogger.com/atom/ns#">portfolio</category><category domain="http://www.blogger.com/atom/ns#">Python</category><category domain="http://www.blogger.com/atom/ns#">recommendation</category><category domain="http://www.blogger.com/atom/ns#">risk tolerance</category><title>Building a Multi‑Agent Finance Chatbot with AG2</title><description>&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg14JYKYf79T4ii7Dw86A3QqUwnV2Qmk-XRd0ylU6TvzO_pbmDwgLxOXFXoUFO7RQaA9BoB2Sauim8pPRugTLgZMGlot1gzigjLiMcBzn_qxJ-uFuqlJVyVeXl-FjMmffDKKg1d6xUvxW6XshSNlkDnF55_UIc8irs7MeM5Rmwvo3qafDQthN4Jox8XpNo/s1258/post.png&quot; style=&quot;clear: left; display: inline !important; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1258&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg14JYKYf79T4ii7Dw86A3QqUwnV2Qmk-XRd0ylU6TvzO_pbmDwgLxOXFXoUFO7RQaA9BoB2Sauim8pPRugTLgZMGlot1gzigjLiMcBzn_qxJ-uFuqlJVyVeXl-FjMmffDKKg1d6xUvxW6XshSNlkDnF55_UIc8irs7MeM5Rmwvo3qafDQthN4Jox8XpNo/s320/post.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&amp;nbsp;Financial conversations often touch on complex markets, risk preferences and compliance constraints.  A single large‑language model may struggle to handle every nuance, so &lt;strong data-end=&quot;230&quot; data-start=&quot;223&quot;&gt;AG2&lt;/strong&gt; (formerly AutoGen) offers a multi‑agent architecture where each agent specializes in part of the workflow.  This article demonstrates how to create a &lt;em data-end=&quot;390&quot; data-start=&quot;381&quot;&gt;finance&lt;/em&gt; chatbot using AG2 and Python.  We will define specialised agents, orchestrate them via a group chat and show a sample interaction.  The approach is inspired by multi‑agent healthcare chatbots but adapted to investment discussions.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 data-end=&quot;651&quot; data-start=&quot;623&quot;&gt;Why multi‑agent chatbots?&lt;/h2&gt;&lt;p data-end=&quot;1508&quot; data-start=&quot;653&quot;&gt;Recent tutorials explain that multi‑agent chatbots divide complex interactions into specialised roles.  Each agent focuses on one task—answering questions, providing recommendations or analysing data—so the overall system can handle nuanced conversations more accurately (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/11/multi-agent-chatbots-with-autogen/#:~:text=Multi,responses%20compared%20to%20a%20single&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/11/multi-agent-chatbots-with-autogen/#:~:text=Multi,responses%20compared%20to%20a%20single&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  The AG2 documentation notes that multi‑agent architectures are easier to maintain and extend; they allow developers to add or remove functionality without redesigning the entire system (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,agents%2C%20one%20can%20compose%20and&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,agents%2C%20one%20can%20compose%20and&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&amp;nbsp; Multi‑agent designs also support different conversation patterns (sequential, group or nested chat) and enable tool use and code execution (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=combining%20models%20and%20agents,&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=combining%20models%20and%20agents,&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  In regulated industries such as healthcare or finance, this modularity improves accuracy and reduces risk (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=There%20are%20at%20least%20two,agent%20systems&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=There%20are%20at%20least%20two,agent%20systems&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;&lt;p data-end=&quot;2074&quot; data-start=&quot;1510&quot;&gt;Another advantage is practicality.  Building a chatbot for stock‑market questions is complex, but packages like &lt;strong data-end=&quot;1634&quot; data-start=&quot;1622&quot;&gt;Chainlit&lt;/strong&gt; and &lt;strong data-end=&quot;1646&quot; data-start=&quot;1639&quot;&gt;AG2&lt;/strong&gt; simplify the process by handling chat orchestration and tool calls (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=Building%20a%20chatbot%20app%20for,AG2%20make%20it%20much%20easier&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=Building%20a%20chatbot%20app%20for,AG2%20make%20it%20much%20easier&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;tinztwinshub.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  These frameworks allow you to run large‑language models locally or through an API and to register Python functions as tools (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=,the%20function%20and%20its%20registration&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=,the%20function%20and%20its%20registration&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;tinztwinshub.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  As open‑source models like Meta’s Llama 3.1 gain popularity, developers can deploy multi‑agent systems on local machines (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=Our%20chatbot%20uses%20Meta%E2%80%99s%20,or%20tools%20to%20the%20application&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=Our%20chatbot%20uses%20Meta%E2%80%99s%20,or%20tools%20to%20the%20application&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;tinztwinshub.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;&lt;h3 data-end=&quot;2093&quot; data-start=&quot;2076&quot;&gt;Pros and cons&lt;/h3&gt;&lt;div class=&quot;_tableContainer_1rjym_1&quot;&gt;&lt;div class=&quot;group _tableWrapper_1rjym_13 flex w-fit flex-col-reverse&quot; tabindex=&quot;-1&quot;&gt;&lt;table class=&quot;w-fit min-w-(--thread-content-width)&quot; data-end=&quot;3548&quot; data-start=&quot;2095&quot;&gt;&lt;thead data-end=&quot;2299&quot; data-start=&quot;2095&quot;&gt;&lt;tr data-end=&quot;2299&quot; data-start=&quot;2095&quot;&gt;&lt;th data-col-size=&quot;sm&quot; data-end=&quot;2119&quot; data-start=&quot;2095&quot;&gt;Aspect&lt;/th&gt;&lt;th data-col-size=&quot;lg&quot; data-end=&quot;2203&quot; data-start=&quot;2119&quot;&gt;Pros&lt;/th&gt;&lt;th data-col-size=&quot;md&quot; data-end=&quot;2299&quot; data-start=&quot;2203&quot;&gt;Cons &amp;amp; Considerations&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody data-end=&quot;3548&quot; data-start=&quot;2505&quot;&gt;&lt;tr data-end=&quot;2746&quot; data-start=&quot;2505&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2528&quot; data-start=&quot;2505&quot;&gt;&lt;strong data-end=&quot;2521&quot; data-start=&quot;2507&quot;&gt;Modularity&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;2644&quot; data-start=&quot;2528&quot;&gt;Each agent has a focused role, making the system easier to extend or modify (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,It%27s%20very&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,It%27s%20very&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;2746&quot; data-start=&quot;2644&quot;&gt;More agents increase the number of interactions to manage and may introduce coordination overhead.&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;2979&quot; data-start=&quot;2747&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2770&quot; data-start=&quot;2747&quot;&gt;&lt;strong data-end=&quot;2767&quot; data-start=&quot;2749&quot;&gt;Specialisation&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;2881&quot; data-start=&quot;2770&quot;&gt;Domain‑specific agents can outperform a monolithic model on their task (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/11/multi-agent-chatbots-with-autogen/#:~:text=Multi,responses%20compared%20to%20a%20single&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/11/multi-agent-chatbots-with-autogen/#:~:text=Multi,responses%20compared%20to%20a%20single&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;2979&quot; data-start=&quot;2881&quot;&gt;Requires careful prompt design to keep agents within their remit and avoid conflicting advice.&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;3258&quot; data-start=&quot;2980&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3003&quot; data-start=&quot;2980&quot;&gt;&lt;strong data-end=&quot;3000&quot; data-start=&quot;2982&quot;&gt;Resource usage&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;3156&quot; data-start=&quot;3003&quot;&gt;Multi‑agent architectures can run cheaper models for some roles while leveraging larger models only where needed (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=,4%20agent&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=,4%20agent&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;3258&quot; data-start=&quot;3156&quot;&gt;Running multiple models in parallel increases latency and can be costly for high‑volume workloads.&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;3548&quot; data-start=&quot;3259&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3283&quot; data-start=&quot;3259&quot;&gt;&lt;strong data-end=&quot;3277&quot; data-start=&quot;3261&quot;&gt;Transparency&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;3444&quot; data-start=&quot;3283&quot;&gt;By exposing distinct agent responses, users can understand how conclusions are derived (e.g., one agent summarises market data, another suggests allocations).&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;3548&quot; data-start=&quot;3444&quot;&gt;In some contexts users may prefer a single, unified answer; too much detail may confuse non‑experts.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 data-end=&quot;3588&quot; data-start=&quot;3550&quot;&gt;Defining the finance chatbot agents&lt;/h2&gt;&lt;p data-end=&quot;3895&quot; data-start=&quot;3590&quot;&gt;Our finance chatbot will engage the user to understand their goals, analyse market conditions and provide general asset‑allocation suggestions.  It is &lt;strong data-end=&quot;3748&quot; data-start=&quot;3741&quot;&gt;not&lt;/strong&gt; a licensed financial adviser; recommendations are for educational purposes.  We adapt the roles from a mental‑health chatbot example into finance:&lt;/p&gt;&lt;ol data-end=&quot;4353&quot; data-start=&quot;3897&quot;&gt;
&lt;li data-end=&quot;3996&quot; data-start=&quot;3897&quot;&gt;
&lt;p data-end=&quot;3996&quot; data-start=&quot;3900&quot;&gt;&lt;strong data-end=&quot;3916&quot; data-start=&quot;3900&quot;&gt;Client&amp;nbsp;Agent&lt;/strong&gt; – Captures the user’s financial situation, risk tolerance and investment goals.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4181&quot; data-start=&quot;3997&quot;&gt;
&lt;p data-end=&quot;4181&quot; data-start=&quot;4000&quot;&gt;&lt;strong data-end=&quot;4025&quot; data-start=&quot;4000&quot;&gt;Market&amp;nbsp;Analysis&amp;nbsp;Agent&lt;/strong&gt; – Analyses the market based on user input.  It summarises macro‑economic trends, asset‑class performance and volatility without giving personalised advice.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4353&quot; data-start=&quot;4182&quot;&gt;
&lt;p data-end=&quot;4353&quot; data-start=&quot;4185&quot;&gt;&lt;strong data-end=&quot;4219&quot; data-start=&quot;4185&quot;&gt;Portfolio&amp;nbsp;Recommendation&amp;nbsp;Agent&lt;/strong&gt; – Suggests a high‑level asset allocation based on the analysis and user profile.  It does not trade or recommend specific securities.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p data-end=&quot;4394&quot; data-start=&quot;4355&quot;&gt;The roles can be summarized as follows:&lt;/p&gt;&lt;div class=&quot;_tableContainer_1rjym_1&quot;&gt;&lt;div class=&quot;group _tableWrapper_1rjym_13 flex w-fit flex-col-reverse&quot; tabindex=&quot;-1&quot;&gt;&lt;table class=&quot;w-fit min-w-(--thread-content-width)&quot; data-end=&quot;5281&quot; data-start=&quot;4396&quot;&gt;&lt;thead data-end=&quot;4452&quot; data-start=&quot;4396&quot;&gt;&lt;tr data-end=&quot;4452&quot; data-start=&quot;4396&quot;&gt;&lt;th data-col-size=&quot;sm&quot; data-end=&quot;4422&quot; data-start=&quot;4396&quot;&gt;Agent&lt;/th&gt;&lt;th data-col-size=&quot;lg&quot; data-end=&quot;4432&quot; data-start=&quot;4422&quot;&gt;Purpose&lt;/th&gt;&lt;th data-col-size=&quot;lg&quot; data-end=&quot;4452&quot; data-start=&quot;4432&quot;&gt;Key instructions&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody data-end=&quot;5281&quot; data-start=&quot;4509&quot;&gt;&lt;tr data-end=&quot;4725&quot; data-start=&quot;4509&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;4535&quot; data-start=&quot;4509&quot;&gt;&lt;strong data-end=&quot;4527&quot; data-start=&quot;4511&quot;&gt;Client&amp;nbsp;Agent&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;4631&quot; data-start=&quot;4535&quot;&gt;Collects information about the user’s financial goals, investment horizon and risk tolerance.&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;4725&quot; data-start=&quot;4631&quot;&gt;Ask the user about their objectives, constraints and any particular interests or concerns.&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;5003&quot; data-start=&quot;4726&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;4754&quot; data-start=&quot;4726&quot;&gt;&lt;strong data-end=&quot;4753&quot; data-start=&quot;4728&quot;&gt;Market&amp;nbsp;Analysis&amp;nbsp;Agent&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;4873&quot; data-start=&quot;4754&quot;&gt;Summarises market conditions, including recent trends in equities, bonds, commodities and macro‑economic indicators.&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;5003&quot; data-start=&quot;4873&quot;&gt;Do not provide personal investment advice; instead, report high‑level insights such as whether markets are volatile or stable.&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;5281&quot; data-start=&quot;5004&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5041&quot; data-start=&quot;5004&quot;&gt;&lt;strong data-end=&quot;5040&quot; data-start=&quot;5006&quot;&gt;Portfolio&amp;nbsp;Recommendation&amp;nbsp;Agent&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;5141&quot; data-start=&quot;5041&quot;&gt;Provides general asset‑allocation suggestions based on the user’s profile and the market summary.&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;5281&quot; data-start=&quot;5141&quot;&gt;Recommend broad categories (e.g., 60&amp;nbsp;% equities, 30&amp;nbsp;% bonds, 10&amp;nbsp;% alternatives); include a disclaimer that this is not financial advice.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 data-end=&quot;5312&quot; data-start=&quot;5283&quot;&gt;Setting up the environment&lt;/h2&gt;&lt;p data-end=&quot;5751&quot; data-start=&quot;5314&quot;&gt;To follow along you need Python 3.11+ and the &lt;code data-end=&quot;5365&quot; data-start=&quot;5360&quot;&gt;ag2&lt;/code&gt; library.  You can install AG2 via pip (&lt;code data-end=&quot;5430&quot; data-start=&quot;5405&quot;&gt;pip install ag2[openai]&lt;/code&gt;).  If you plan to run local models, install an API wrapper like &lt;code data-end=&quot;5503&quot; data-start=&quot;5495&quot;&gt;ollama&lt;/code&gt; and download a model such as Llama&amp;nbsp;3.1 (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=Our%20chatbot%20uses%20Meta%E2%80%99s%20,or%20tools%20to%20the%20application&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=Our%20chatbot%20uses%20Meta%E2%80%99s%20,or%20tools%20to%20the%20application&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;tinztwinshub.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  You will also need API keys if using cloud models.  In this example we configure the LLM via &lt;code data-end=&quot;5689&quot; data-start=&quot;5677&quot;&gt;llm_config&lt;/code&gt; without specifying an API key; supply your own key as needed.&lt;/p&gt;&lt;h2 data-end=&quot;5779&quot; data-start=&quot;5753&quot;&gt;Implementing the agents&lt;/h2&gt;&lt;p data-end=&quot;6000&quot; data-start=&quot;5781&quot;&gt;The following Python code illustrates how to create the finance chatbot.  It borrows the group‑chat structure from the mental‑health example and uses AG2’s &lt;code data-end=&quot;5955&quot; data-start=&quot;5937&quot;&gt;ConversableAgent&lt;/code&gt;, &lt;code data-end=&quot;5968&quot; data-start=&quot;5957&quot;&gt;GroupChat&lt;/code&gt; and &lt;code data-end=&quot;5991&quot; data-start=&quot;5973&quot;&gt;GroupChatManager&lt;/code&gt; classes:&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;8899&quot; data-start=&quot;6002&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-python&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; autogen &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; ConversableAgent, GroupChat, GroupChatManager

&lt;span class=&quot;hljs-comment&quot;&gt;# Replace None with your OpenAI or local model API key if required&lt;/span&gt;
llm_config = {&lt;span class=&quot;hljs-string&quot;&gt;&quot;config_list&quot;&lt;/span&gt;: [{&lt;span class=&quot;hljs-string&quot;&gt;&quot;model&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;gpt-4o&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;api_key&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-literal&quot;&gt;None&lt;/span&gt;}]}

&lt;span class=&quot;hljs-comment&quot;&gt;# 1. Client Agent: collects user goals and risk tolerance&lt;/span&gt;
client_agent = ConversableAgent(
    name=&lt;span class=&quot;hljs-string&quot;&gt;&quot;client&quot;&lt;/span&gt;,
    system_message=(
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;You are the client interface.\n&quot;&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;Your job is to describe your financial goals, risk tolerance, investment horizon, &quot;&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;and any budget constraints or ethical considerations.&quot;&lt;/span&gt;
    ),
    llm_config=llm_config
)

&lt;span class=&quot;hljs-comment&quot;&gt;# 2. Market Analysis Agent: summarises current market conditions&lt;/span&gt;
market_analysis_agent = ConversableAgent(
    name=&lt;span class=&quot;hljs-string&quot;&gt;&quot;market_analysis&quot;&lt;/span&gt;,
    system_message=(
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;You analyse the current market based on the client&#39;s input.&quot;&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;Summarise macroeconomic factors (interest rates, inflation), sector trends and recent market volatility. &quot;&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;Do not provide personalised investment advice; simply report high-level observations.&quot;&lt;/span&gt;
    ),
    llm_config=llm_config
)

&lt;span class=&quot;hljs-comment&quot;&gt;# 3. Portfolio Recommendation Agent: proposes a high-level allocation&lt;/span&gt;
portfolio_recommendation_agent = ConversableAgent(
    name=&lt;span class=&quot;hljs-string&quot;&gt;&quot;portfolio_recommendation&quot;&lt;/span&gt;,
    system_message=(
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;You suggest a general asset allocation based on the analysis from the Market Analysis Agent.&quot;&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;Consider the client&#39;s risk tolerance and goals.&quot;&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;Recommend proportions across asset classes such as equities, bonds, and alternatives.&quot;&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;Include a disclaimer that the suggestions are educational and not financial advice.&quot;&lt;/span&gt;
    ),
    llm_config=llm_config
)

&lt;span class=&quot;hljs-comment&quot;&gt;# Configure a group chat where the analysis and recommendation agents converse&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;# The manager orchestrates turn-taking in round‑robin fashion&lt;/span&gt;
finance_groupchat = GroupChat(
    agents=[market_analysis_agent, portfolio_recommendation_agent],
    messages=[],
    max_round=&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;,
    speaker_selection_method=&lt;span class=&quot;hljs-string&quot;&gt;&quot;round_robin&quot;&lt;/span&gt;
)

manager = GroupChatManager(name=&lt;span class=&quot;hljs-string&quot;&gt;&quot;manager&quot;&lt;/span&gt;, groupchat=finance_groupchat)

&lt;span class=&quot;hljs-comment&quot;&gt;# Function to start the finance chatbot&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;start_finance_chat&lt;/span&gt;():
    &lt;span class=&quot;hljs-built_in&quot;&gt;print&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;\nWelcome to the AI Finance Chatbot!&quot;&lt;/span&gt;)
    user_input = &lt;span class=&quot;hljs-built_in&quot;&gt;input&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Please describe your financial goals and risk tolerance: &quot;&lt;/span&gt;)

    &lt;span class=&quot;hljs-comment&quot;&gt;# The client agent initiates the conversation with the manager&lt;/span&gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;print&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;\nAnalysing your profile and market conditions...&quot;&lt;/span&gt;)
    response = client_agent.initiate_chat(
        manager,
        message=(
            &lt;span class=&quot;hljs-string&quot;&gt;f&quot;My financial goals and risk tolerance are: &lt;span class=&quot;hljs-subst&quot;&gt;{user_input}&lt;/span&gt;&lt;/span&gt;. &quot;
            &lt;span class=&quot;hljs-string&quot;&gt;&quot;Based on this, what insights and recommendations can you provide?&quot;&lt;/span&gt;
        )
    )

    &lt;span class=&quot;hljs-comment&quot;&gt;# Fallback in case the first response is empty&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;not&lt;/span&gt; response:
        response = portfolio_recommendation_agent.initiate_chat(
            manager,
            message=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Based on the client&#39;s goals, please provide portfolio recommendations.&quot;&lt;/span&gt;
        )

&lt;span class=&quot;hljs-comment&quot;&gt;# Run the chatbot&lt;/span&gt;
start_finance_chat()
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;h3 data-end=&quot;8917&quot; data-start=&quot;8901&quot;&gt;How it works&lt;/h3&gt;&lt;ol data-end=&quot;9766&quot; data-start=&quot;8919&quot;&gt;
&lt;li data-end=&quot;9082&quot; data-start=&quot;8919&quot;&gt;
&lt;p data-end=&quot;9082&quot; data-start=&quot;8922&quot;&gt;&lt;strong data-end=&quot;8936&quot; data-start=&quot;8922&quot;&gt;User input&lt;/strong&gt; – The &lt;code data-end=&quot;8957&quot; data-start=&quot;8943&quot;&gt;client_agent&lt;/code&gt; collects the investor’s goals and risk tolerance.  In a real deployment you might ask follow‑up questions to ensure clarity.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;9330&quot; data-start=&quot;9083&quot;&gt;
&lt;p data-end=&quot;9330&quot; data-start=&quot;9086&quot;&gt;&lt;strong data-end=&quot;9105&quot; data-start=&quot;9086&quot;&gt;Market analysis&lt;/strong&gt; – The &lt;code data-end=&quot;9135&quot; data-start=&quot;9112&quot;&gt;market_analysis_agent&lt;/code&gt; reviews the input and provides a concise summary of current market conditions.  It does not provide personalised advice, reflecting a common compliance requirement for general market commentary.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;9532&quot; data-start=&quot;9331&quot;&gt;
&lt;p data-end=&quot;9532&quot; data-start=&quot;9334&quot;&gt;&lt;strong data-end=&quot;9358&quot; data-start=&quot;9334&quot;&gt;Portfolio suggestion&lt;/strong&gt; – The &lt;code data-end=&quot;9397&quot; data-start=&quot;9365&quot;&gt;portfolio_recommendation_agent&lt;/code&gt; uses the market summary and client profile to recommend an asset allocation.  It emphasises diversification and includes a disclaimer.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;9766&quot; data-start=&quot;9533&quot;&gt;
&lt;p data-end=&quot;9766&quot; data-start=&quot;9536&quot;&gt;&lt;strong data-end=&quot;9561&quot; data-start=&quot;9536&quot;&gt;Group chat management&lt;/strong&gt; – The &lt;code data-end=&quot;9586&quot; data-start=&quot;9568&quot;&gt;GroupChatManager&lt;/code&gt; coordinates the exchange.  We use a round‑robin method to ensure both agents contribute (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/11/multi-agent-chatbots-with-autogen/#:~:text=import%20autogen&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/11/multi-agent-chatbots-with-autogen/#:~:text=import%20autogen&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  The &lt;code data-end=&quot;9731&quot; data-start=&quot;9720&quot;&gt;max_round&lt;/code&gt; parameter prevents infinite loops.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;h4 data-end=&quot;9791&quot; data-start=&quot;9768&quot;&gt;Sample interaction&lt;/h4&gt;&lt;p data-end=&quot;9953&quot; data-start=&quot;9793&quot;&gt;Suppose a user says: &lt;em data-end=&quot;9915&quot; data-start=&quot;9814&quot;&gt;“I’m saving for retirement in 20&amp;nbsp;years, have moderate risk tolerance and want to invest ethically.”&lt;/em&gt;  The agents might respond as follows:&lt;/p&gt;&lt;blockquote data-end=&quot;10703&quot; data-start=&quot;9955&quot;&gt;
&lt;p data-end=&quot;10300&quot; data-start=&quot;9957&quot;&gt;&lt;strong data-end=&quot;9983&quot; data-start=&quot;9957&quot;&gt;Market&amp;nbsp;Analysis&amp;nbsp;Agent:&lt;/strong&gt; “Based on the current environment, central banks are signalling that interest rates may remain high to curb inflation, equities have been volatile with technology and renewable‑energy sectors outperforming, and bond yields offer moderate returns.  Commodities like gold have appreciated due to geopolitical tension.”&lt;/p&gt;
&lt;p data-end=&quot;10703&quot; data-start=&quot;10305&quot;&gt;&lt;strong data-end=&quot;10340&quot; data-start=&quot;10305&quot;&gt;Portfolio&amp;nbsp;Recommendation&amp;nbsp;Agent:&lt;/strong&gt; “Given your 20‑year horizon and moderate risk tolerance, a diversified allocation could be 60&amp;nbsp;% equities (with a tilt towards ESG‑focused funds), 30&amp;nbsp;% bonds (combining government and investment‑grade corporate bonds), and 10&amp;nbsp;% alternatives such as real‑estate investment trusts or commodities.  This is general information and not personalised financial advice.”&lt;/p&gt;
&lt;/blockquote&gt;&lt;p data-end=&quot;10955&quot; data-start=&quot;10705&quot;&gt;In a real‑world application you could register functions that fetch real‑time market data or compute portfolio statistics using AG2’s &lt;code data-end=&quot;10858&quot; data-start=&quot;10839&quot;&gt;register_function&lt;/code&gt; API (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=,the%20function%20and%20its%20registration&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=,the%20function%20and%20its%20registration&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;tinztwinshub.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;, but our simple example relies on the language model.&lt;/p&gt;&lt;h2 data-end=&quot;10990&quot; data-start=&quot;10957&quot;&gt;Pros and cons of this approach&lt;/h2&gt;&lt;ul data-end=&quot;12200&quot; data-start=&quot;10992&quot;&gt;
&lt;li data-end=&quot;11623&quot; data-start=&quot;10992&quot;&gt;
&lt;p data-end=&quot;11003&quot; data-start=&quot;10994&quot;&gt;&lt;strong data-end=&quot;11003&quot; data-start=&quot;10994&quot;&gt;Pros:&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;11623&quot; data-start=&quot;11006&quot;&gt;
&lt;li data-end=&quot;11265&quot; data-start=&quot;11006&quot;&gt;
&lt;p data-end=&quot;11265&quot; data-start=&quot;11008&quot;&gt;&lt;em data-end=&quot;11039&quot; data-start=&quot;11008&quot;&gt;Modularity and specialisation&lt;/em&gt; – Each agent has a clear purpose, which can improve the relevance and quality of responses (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,agents%2C%20one%20can%20compose%20and&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,agents%2C%20one%20can%20compose%20and&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  For example, one agent summarises macro data while another focuses on portfolio construction.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;11461&quot; data-start=&quot;11268&quot;&gt;
&lt;p data-end=&quot;11461&quot; data-start=&quot;11270&quot;&gt;&lt;em data-end=&quot;11289&quot; data-start=&quot;11270&quot;&gt;Ease of extension&lt;/em&gt; – You can add agents to handle regulatory checks, tax considerations or portfolio rebalancing without rewriting existing components (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,agents%2C%20one%20can%20compose%20and&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,agents%2C%20one%20can%20compose%20and&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;11623&quot; data-start=&quot;11464&quot;&gt;
&lt;p data-end=&quot;11623&quot; data-start=&quot;11466&quot;&gt;&lt;em data-end=&quot;11480&quot; data-start=&quot;11466&quot;&gt;Transparency&lt;/em&gt; – Users can see how the system arrives at recommendations because each agent’s contribution is visible (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=Benefits%20of%20multi&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=Benefits%20of%20multi&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;12200&quot; data-start=&quot;11625&quot;&gt;
&lt;p data-end=&quot;11636&quot; data-start=&quot;11627&quot;&gt;&lt;strong data-end=&quot;11636&quot; data-start=&quot;11627&quot;&gt;Cons:&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;12200&quot; data-start=&quot;11639&quot;&gt;
&lt;li data-end=&quot;11794&quot; data-start=&quot;11639&quot;&gt;
&lt;p data-end=&quot;11794&quot; data-start=&quot;11641&quot;&gt;&lt;em data-end=&quot;11664&quot; data-start=&quot;11641&quot;&gt;Coordination overhead&lt;/em&gt; – More agents mean more messages and potential latency.  Tuning &lt;code data-end=&quot;11740&quot; data-start=&quot;11729&quot;&gt;max_round&lt;/code&gt; and speaker selection helps avoid long conversations.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;11971&quot; data-start=&quot;11797&quot;&gt;
&lt;p data-end=&quot;11971&quot; data-start=&quot;11799&quot;&gt;&lt;em data-end=&quot;11818&quot; data-start=&quot;11799&quot;&gt;Prompt management&lt;/em&gt; – Agents must be carefully prompted to avoid stepping outside their roles.  If the market‑analysis agent gives advice, it could cause compliance issues.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;12200&quot; data-start=&quot;11974&quot;&gt;
&lt;p data-end=&quot;12200&quot; data-start=&quot;11976&quot;&gt;&lt;em data-end=&quot;11992&quot; data-start=&quot;11976&quot;&gt;Resource usage&lt;/em&gt; – Running multiple models or using powerful models for each agent can be costly.  Techniques like mixing cheap and expensive models or limiting context length can help (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=,4%20agent&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=,4%20agent&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;h2 data-end=&quot;12224&quot; data-start=&quot;12202&quot;&gt;Future enhancements&lt;/h2&gt;&lt;ul data-end=&quot;13221&quot; data-start=&quot;12226&quot;&gt;
&lt;li data-end=&quot;12539&quot; data-start=&quot;12226&quot;&gt;
&lt;p data-end=&quot;12539&quot; data-start=&quot;12228&quot;&gt;&lt;strong data-end=&quot;12259&quot; data-start=&quot;12228&quot;&gt;Real‑time data integration:&lt;/strong&gt; Register functions to call APIs (e.g., yfinance, Bloomberg, or custom data feeds) so the analysis agent can deliver up‑to‑the‑minute market summaries.  The Tinz&amp;nbsp;Twins example shows how to plot year‑to‑date gains using a registered function (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=,the%20function%20and%20its%20registration&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://tinztwinshub.com/investment-research/build-a-multi-agent-stock-market-analyst-to-compare-stock-price-performance/#:~:text=,the%20function%20and%20its%20registration&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;tinztwinshub.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;12741&quot; data-start=&quot;12540&quot;&gt;
&lt;p data-end=&quot;12741&quot; data-start=&quot;12542&quot;&gt;&lt;strong data-end=&quot;12568&quot; data-start=&quot;12542&quot;&gt;Regulatory compliance:&lt;/strong&gt; Add an agent that checks whether recommendations adhere to regional regulations (e.g., MIFID&amp;nbsp;II or SEC guidelines).  It could flag issues before suggestions reach the user.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;13022&quot; data-start=&quot;12742&quot;&gt;
&lt;p data-end=&quot;13022&quot; data-start=&quot;12744&quot;&gt;&lt;strong data-end=&quot;12779&quot; data-start=&quot;12744&quot;&gt;Advanced conversation patterns:&lt;/strong&gt; Use nested or constrained group chats to handle multi‑step workflows, such as gathering risk questionnaires, performing Monte‑Carlo simulations and then generating a report.  AG2 supports these patterns (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=combining%20models%20and%20agents,&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=combining%20models%20and%20agents,&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;13221&quot; data-start=&quot;13023&quot;&gt;
&lt;p data-end=&quot;13221&quot; data-start=&quot;13025&quot;&gt;&lt;strong data-end=&quot;13048&quot; data-start=&quot;13025&quot;&gt;Multi‑modal output:&lt;/strong&gt; Integrate charting tools to visualise asset allocations or risk/return trade‑offs.  For instance, register a function that plots allocation pie charts and returns an image.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;h2 data-end=&quot;13236&quot; data-start=&quot;13223&quot;&gt;Conclusion&lt;/h2&gt;&lt;p&gt;



























&lt;/p&gt;&lt;p data-end=&quot;14083&quot; data-start=&quot;13238&quot;&gt;AG2’s multi‑agent architecture makes it straightforward to build tailored chatbots for complex domains such as finance.  By dividing the conversation into specialised roles, developers can achieve greater accuracy, transparency and extensibility compared with monolithic chatbots (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/11/multi-agent-chatbots-with-autogen/#:~:text=Multi,responses%20compared%20to%20a%20single&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/11/multi-agent-chatbots-with-autogen/#:~:text=Multi,responses%20compared%20to%20a%20single&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  The simple example above illustrates how you can adapt a mental‑health chatbot pattern to a personal‑finance advisor.  Although multi‑agent systems introduce coordination challenges and resource overhead, careful design and modern frameworks like AG2 or Chainlit can mitigate these issues (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,It%27s%20very&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://docs.ag2.ai/0.8.7/docs/blog/2024/05/24/Agent/#:~:text=The%20multi,It%27s%20very&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;docs.ag2.ai&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  As open‑source models and tooling evolve, we can expect multi‑agent finance chatbots to become more capable—potentially integrating real‑time data, compliance checks and sophisticated analytics.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2025/10/building-multiagent-finance-chatbot.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg14JYKYf79T4ii7Dw86A3QqUwnV2Qmk-XRd0ylU6TvzO_pbmDwgLxOXFXoUFO7RQaA9BoB2Sauim8pPRugTLgZMGlot1gzigjLiMcBzn_qxJ-uFuqlJVyVeXl-FjMmffDKKg1d6xUvxW6XshSNlkDnF55_UIc8irs7MeM5Rmwvo3qafDQthN4Jox8XpNo/s72-c/post.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>London, UK</georss:featurename><georss:point>51.5072178 -0.1275862</georss:point><georss:box>23.196983963821154 -35.2838362 79.817451636178845 35.0286638</georss:box></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-6691039309025967621</guid><pubDate>Sat, 11 Oct 2025 18:41:00 +0000</pubDate><atom:updated>2026-03-15T21:41:43.688+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Agentic AI</category><category domain="http://www.blogger.com/atom/ns#">AI Agents</category><category domain="http://www.blogger.com/atom/ns#">AI Chatbot</category><category domain="http://www.blogger.com/atom/ns#">Compliance Automation</category><category domain="http://www.blogger.com/atom/ns#">CrewAI</category><category domain="http://www.blogger.com/atom/ns#">ESMA</category><category domain="http://www.blogger.com/atom/ns#">Financial Regulation</category><category domain="http://www.blogger.com/atom/ns#">GPT-4o</category><category domain="http://www.blogger.com/atom/ns#">HuggingFace</category><category domain="http://www.blogger.com/atom/ns#">MiFID II</category><category domain="http://www.blogger.com/atom/ns#">MiFIR</category><category domain="http://www.blogger.com/atom/ns#">openAI</category><category domain="http://www.blogger.com/atom/ns#">PDFSearchTool</category><category domain="http://www.blogger.com/atom/ns#">RegTech</category><category domain="http://www.blogger.com/atom/ns#">Task-Centric AI</category><title>Building a MiFID II Compliance Chatbot with CrewAI</title><description>&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKVOPmJuVHpPEhxkDQ2Sj6ingI7wZ0Ws9zVFQcLCDR1qkPnEy1-yP-g5giG3WC1Gw2GfjRj6UJphLVY275G07DoGmsBtye8REn3q7NhHc7hJ2GGAT2E5yRsxoqRPkZqJzMlIMNCREUFrWKvAzvH1mWTstt1u_jhcK8uhl-vk6mp3dt2ChWacW2azK5b34/s1024/ChatGPT%20Image%20Oct%2010,%202025,%2007_11_05%20PM.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1024&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKVOPmJuVHpPEhxkDQ2Sj6ingI7wZ0Ws9zVFQcLCDR1qkPnEy1-yP-g5giG3WC1Gw2GfjRj6UJphLVY275G07DoGmsBtye8REn3q7NhHc7hJ2GGAT2E5yRsxoqRPkZqJzMlIMNCREUFrWKvAzvH1mWTstt1u_jhcK8uhl-vk6mp3dt2ChWacW2azK5b34/s320/ChatGPT%20Image%20Oct%2010,%202025,%2007_11_05%20PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;Financial regulation is notoriously complex. Investment firms must interpret and comply with lengthy documents such as the&amp;nbsp;&lt;em data-end=&quot;1090&quot; data-start=&quot;1046&quot;&gt;Markets in Financial Instruments Directive&lt;/em&gt;&amp;nbsp;(MiFID&amp;nbsp;II) and its companion regulation (MiFIR), while preparing for MiFID&amp;nbsp;III. Compliance officers routinely pore over hundreds of pages of policy statements, ESMA Q&amp;amp;As and Regulatory Technical Standards (RTS). At the same time, regulators are tightening expectations: by September&amp;nbsp;2025 firms will need to implement the MiFID&amp;nbsp;III amendments and be ready to demonstrate that surveillance and inducement controls work across every channel&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=9%3A12&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=9%3A12&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;&amp;nbsp;(luware.com&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=communications%20that%20may%20lead%20to,auditable%20communications%20across%20all%20channels&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=communications%20that%20may%20lead%20to,auditable%20communications%20across%20all%20channels&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;. Manual search is inefficient and error‑prone.&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;/p&gt;&lt;p data-end=&quot;2068&quot; data-start=&quot;1654&quot;&gt;This article shows how to build a&amp;nbsp;&lt;strong data-end=&quot;1719&quot; data-start=&quot;1688&quot;&gt;MiFID&amp;nbsp;II compliance chatbot&lt;/strong&gt;&amp;nbsp;using CrewAI, a multi‑agent framework. You will learn how to organise the workflow, assign tools at the agent or task level, avoid common validation errors, and anticipate upcoming regulatory changes. The techniques apply beyond finance; they illustrate a pattern for building reliable agentic systems that combine retrieval with language models.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class=&quot;_tableContainer_1rjym_1&quot;&gt;&lt;div class=&quot;group _tableWrapper_1rjym_13 flex w-fit flex-col-reverse&quot; tabindex=&quot;-1&quot;&gt;&lt;table class=&quot;w-fit min-w-(--thread-content-width)&quot; data-end=&quot;903&quot; data-start=&quot;66&quot;&gt;&lt;thead data-end=&quot;86&quot; data-start=&quot;66&quot;&gt;&lt;tr data-end=&quot;86&quot; data-start=&quot;66&quot;&gt;&lt;th data-col-size=&quot;sm&quot; data-end=&quot;75&quot; data-start=&quot;66&quot;&gt;&lt;/th&gt;&lt;th data-col-size=&quot;lg&quot; data-end=&quot;86&quot; data-start=&quot;75&quot;&gt;&lt;br /&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody data-end=&quot;903&quot; data-start=&quot;97&quot;&gt;&lt;tr data-end=&quot;213&quot; data-start=&quot;97&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;113&quot; data-start=&quot;97&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;213&quot; data-start=&quot;113&quot;&gt;&lt;strong data-end=&quot;112&quot; data-start=&quot;99&quot;&gt;Framework&lt;/strong&gt;&lt;br /&gt;CrewAI orchestrates multiple AI agents to search MiFID-related PDFs and draft compliance answers&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;321&quot; data-start=&quot;214&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;229&quot; data-start=&quot;214&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;321&quot; data-start=&quot;229&quot;&gt;&lt;strong data-end=&quot;228&quot; data-start=&quot;216&quot;&gt;Approach&lt;/strong&gt;&lt;br /&gt;Compare agent‑centric vs task‑centric tool assignment for reliability and predictability&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;453&quot; data-start=&quot;322&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;336&quot; data-start=&quot;322&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;453&quot; data-start=&quot;336&quot;&gt;&lt;strong data-end=&quot;335&quot; data-start=&quot;324&quot;&gt;Key Fix&lt;/strong&gt;&lt;br /&gt;Teach the language model to include the mandatory &lt;code data-end=&quot;409&quot; data-start=&quot;388&quot;&gt;{&quot;query&quot;: &quot;&amp;lt;text&amp;gt;&quot;}&lt;/code&gt; argument when calling the PDF search tool&lt;br /&gt;&lt;br /&gt;&lt;strong data-end=&quot;478&quot; data-start=&quot;456&quot;&gt;Regulatory Horizon&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;660&quot; data-start=&quot;454&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;479&quot; data-start=&quot;454&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;660&quot; data-start=&quot;479&quot;&gt;MiFID&amp;nbsp;III amendments enter force March&amp;nbsp;28&amp;nbsp;2024 with a main implementation deadline of September&amp;nbsp;29&amp;nbsp;2025 (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=9%3A12&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=9%3A12&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=MiFID%20III%20follows%20a%20structured,compliance%20strategies%20with%20these%20milestones&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=MiFID%20III%20follows%20a%20structured,compliance%20strategies%20with%20these%20milestones&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;table class=&quot;w-fit min-w-(--thread-content-width)&quot; data-end=&quot;903&quot; data-start=&quot;66&quot;&gt;&lt;tbody data-end=&quot;903&quot; data-start=&quot;97&quot;&gt;&lt;tr data-end=&quot;903&quot; data-start=&quot;661&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;680&quot; data-start=&quot;661&quot;&gt;&lt;strong data-end=&quot;679&quot; data-start=&quot;663&quot;&gt;New Features&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;903&quot; data-start=&quot;680&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;903&quot; data-start=&quot;661&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;680&quot; data-start=&quot;661&quot;&gt;&lt;/td&gt;&lt;td data-col-size=&quot;lg&quot; data-end=&quot;903&quot; data-start=&quot;680&quot;&gt;CrewAI’s MCP standardises tool access and data sources (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=MCP%20&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=MCP%20&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt; while guardrails and event buses increase reliability (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Guardrails&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Guardrails&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=CrewAI%20now%20includes%20an%20event,the%20following%20events%20are%20emitted&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=CrewAI%20now%20includes%20an%20event,the%20following%20events%20are%20emitted&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 data-end=&quot;920&quot; data-start=&quot;905&quot;&gt;Agent‑centric vs Task‑centric Tool Assignment&lt;/h2&gt;&lt;p data-end=&quot;2466&quot; data-start=&quot;2261&quot;&gt;CrewAI allows tools—such as a PDF searcher or a web search API—to be provided either to the &lt;em data-end=&quot;2360&quot; data-start=&quot;2353&quot;&gt;agent&lt;/em&gt; as a global toolbox or to individual &lt;em data-end=&quot;2405&quot; data-start=&quot;2398&quot;&gt;tasks&lt;/em&gt;.  These two patterns affect reliability and maintainability.&lt;/p&gt;&lt;h3 data-end=&quot;2498&quot; data-start=&quot;2468&quot;&gt;Agent‑centric (Generalist)&lt;/h3&gt;&lt;p data-end=&quot;2926&quot; data-start=&quot;2500&quot;&gt;In this common setup the agent receives a list of tools that it may call at any time.  The agent decides which tool to use based on the prompt and its internal reasoning.  This is flexible and quick to prototype, but it can lead to mis‑calls.  For example, the PDF search tool expects a JSON argument with a &lt;code data-end=&quot;2815&quot; data-start=&quot;2808&quot;&gt;query&lt;/code&gt; string.  Without explicit instructions, the LLM may omit the argument, leading to the familiar Pydantic error:&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;2994&quot; data-start=&quot;2928&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre!&quot;&gt;&lt;span class=&quot;hljs-title class_&quot;&gt;Error&lt;/span&gt;: &lt;span class=&quot;hljs-title class_&quot;&gt;Arguments&lt;/span&gt; validation &lt;span class=&quot;hljs-attr&quot;&gt;failed&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;`query`&lt;/span&gt; field required
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;3262&quot; data-start=&quot;2996&quot;&gt;When the agent owns the entire toolbox, every task must encode tool‑calling rules in its prompt to avoid such errors.  In our experience this reduces predictability as the system grows; even seasoned engineers forget to repeat the tool signature in each description.&lt;/p&gt;&lt;h3 data-end=&quot;3293&quot; data-start=&quot;3264&quot;&gt;Task‑centric (Specialist)&lt;/h3&gt;&lt;p data-end=&quot;3632&quot; data-start=&quot;3295&quot;&gt;The task‑centric approach grants tools &lt;strong data-end=&quot;3342&quot; data-start=&quot;3334&quot;&gt;only&lt;/strong&gt; to the tasks that need them.  When the agent begins a task it is temporarily given the required tools and cannot access others.  This design leads to more predictable tool calls because the agent knows &lt;em data-end=&quot;3552&quot; data-start=&quot;3545&quot;&gt;which&lt;/em&gt; tools are available for that job and the prompt can focus on &lt;em data-end=&quot;3619&quot; data-start=&quot;3614&quot;&gt;how&lt;/em&gt; to use them.&lt;/p&gt;&lt;p data-end=&quot;3947&quot; data-start=&quot;3634&quot;&gt;In regulated domains this scoping is critical.  It reduces the chance that a general‑purpose LLM will call a web search when only document evidence is allowed, and it makes unit testing straightforward: each task can be executed in isolation with its own tools and guardrails (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Guardrails&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Guardrails&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;&lt;h3 data-end=&quot;3966&quot; data-start=&quot;3949&quot;&gt;Pros and Cons&lt;/h3&gt;&lt;ul data-end=&quot;4452&quot; data-start=&quot;3968&quot;&gt;
&lt;li data-end=&quot;4207&quot; data-start=&quot;3968&quot;&gt;
&lt;p data-end=&quot;3990&quot; data-start=&quot;3970&quot;&gt;&lt;strong data-end=&quot;3987&quot; data-start=&quot;3970&quot;&gt;Agent‑centric&lt;/strong&gt;:&lt;/p&gt;
&lt;ul data-end=&quot;4207&quot; data-start=&quot;3993&quot;&gt;
&lt;li data-end=&quot;4079&quot; data-start=&quot;3993&quot;&gt;
&lt;p data-end=&quot;4079&quot; data-start=&quot;3995&quot;&gt;&lt;em data-end=&quot;4001&quot; data-start=&quot;3995&quot;&gt;Pros&lt;/em&gt;: Simple configuration; fewer moving parts; agent decides which tool to use.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4207&quot; data-start=&quot;4082&quot;&gt;
&lt;p data-end=&quot;4207&quot; data-start=&quot;4084&quot;&gt;&lt;em data-end=&quot;4090&quot; data-start=&quot;4084&quot;&gt;Cons&lt;/em&gt;: LLM may mis‑call tools without guidance; prompts must repeat tool signatures; difficult to test tasks in isolation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4452&quot; data-start=&quot;4208&quot;&gt;
&lt;p data-end=&quot;4229&quot; data-start=&quot;4210&quot;&gt;&lt;strong data-end=&quot;4226&quot; data-start=&quot;4210&quot;&gt;Task‑centric&lt;/strong&gt;:&lt;/p&gt;
&lt;ul data-end=&quot;4452&quot; data-start=&quot;4232&quot;&gt;
&lt;li data-end=&quot;4367&quot; data-start=&quot;4232&quot;&gt;
&lt;p data-end=&quot;4367&quot; data-start=&quot;4234&quot;&gt;&lt;em data-end=&quot;4240&quot; data-start=&quot;4234&quot;&gt;Pros&lt;/em&gt;: Predictable and secure; tools scoped to tasks; easier to unit‑test and update; better adherence to compliance restrictions.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4452&quot; data-start=&quot;4370&quot;&gt;
&lt;p data-end=&quot;4452&quot; data-start=&quot;4372&quot;&gt;&lt;em data-end=&quot;4378&quot; data-start=&quot;4372&quot;&gt;Cons&lt;/em&gt;: Slightly more verbose setup; requires careful mapping of tasks to tools.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;h2 data-end=&quot;4473&quot; data-start=&quot;4454&quot;&gt;Code Walkthrough&lt;/h2&gt;&lt;p data-end=&quot;4735&quot; data-start=&quot;4475&quot;&gt;Let’s examine the core elements of the chatbot.  The code below instantiates an LLM, sets up PDF search tools for each regulatory document, defines an agent with a system prompt and tool‑calling guide, and creates two tasks orchestrated sequentially by a crew. Code can be found here: (&lt;a href=&quot;https://github.com/JordiCorbilla/langgraph-cookbook/tree/main/09%20-%20Mifid%20CrewAI%20Chatbot&quot;&gt;langgraph-cookbook/09 - Mifid CrewAI Chatbot at main · JordiCorbilla/langgraph-cookbook&lt;/a&gt;)&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;7152&quot; data-start=&quot;4737&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-python&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; crewai &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; Agent, Task, Crew, Process
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; crewai &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; LLM
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; crewai_tools &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; PDFSearchTool, SerperDevTool

llm = LLM(model=&lt;span class=&quot;hljs-string&quot;&gt;&quot;openai/gpt-4o-mini&quot;&lt;/span&gt;)

web_search_tool = SerperDevTool()

pdf_search_tool = PDFSearchTool(
    pdf=&lt;span class=&quot;hljs-string&quot;&gt;&quot;https://www.fca.org.uk/publication/policy/ps17-14.pdf&quot;&lt;/span&gt;,
    config={ &lt;span class=&quot;hljs-string&quot;&gt;&#39;embedder&#39;&lt;/span&gt;: { &lt;span class=&quot;hljs-string&quot;&gt;&#39;provider&#39;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;huggingface&#39;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&#39;config&#39;&lt;/span&gt;: { &lt;span class=&quot;hljs-string&quot;&gt;&#39;model&#39;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;sentence-transformers/all-MiniLM-L6-v2&#39;&lt;/span&gt; } } }
)
pdf_search_tool2 = PDFSearchTool(
    pdf=&lt;span class=&quot;hljs-string&quot;&gt;&quot;https://www.fca.org.uk/publication/consultation/cp16-19.pdf&quot;&lt;/span&gt;,
    config={ ... }
)
pdf_search_tool3 = PDFSearchTool(
    pdf=&lt;span class=&quot;hljs-string&quot;&gt;&quot;https://www.esma.europa.eu/sites/default/files/library/2016-1452_guidelines_mifid_ii_transaction_reporting.pdf&quot;&lt;/span&gt;,
    config={ ... }
)

COMPLIANCE_SYSTEM_PROMPT = &lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&quot;
You are a MiFID II / MiFIR compliance analyst. Answer ONLY with information grounded in the provided PDFs.  Always include article‑level citations.  Prefer the latest ESMA RTS for conflicts.  No speculation.
&quot;&quot;&quot;&lt;/span&gt;

CITATION_FORMAT_PROMPT = &lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&quot;
Format citations as markdown footnotes: [MiFID II&amp;nbsp;Art&amp;nbsp;X(Y)](SOURCE_URL#page=?), [MiFIR&amp;nbsp;Art&amp;nbsp;X(Y)](SOURCE_URL#page=?).
&quot;&quot;&quot;&lt;/span&gt;

TOOL_CALLING_GUIDE = &lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&quot;
When using &quot;Search a PDF&#39;s content&quot;, you MUST pass a JSON argument like {&quot;query&quot;: &quot;&amp;lt;short search string&amp;gt;&quot;}.  Never omit &#39;query&#39;.
&quot;&quot;&quot;&lt;/span&gt;

agent_centric_agent = Agent(
    role=&lt;span class=&quot;hljs-string&quot;&gt;&quot;MiFID Compliance Analyst&quot;&lt;/span&gt;,
    goal=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Answer MiFID II / MiFIR questions with exact citations.&quot;&lt;/span&gt;,
    backstory=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Seasoned regulatory analyst trained on MiFID II, MiFIR and FCA/ESMA RTS/Q&amp;amp;A.&quot;&lt;/span&gt;,
    tools=[pdf_search_tool, pdf_search_tool2, pdf_search_tool3, web_search_tool],
    llm=llm,
    system_prompt=COMPLIANCE_SYSTEM_PROMPT + CITATION_FORMAT_PROMPT + TOOL_CALLING_GUIDE
)

&lt;span class=&quot;hljs-comment&quot;&gt;# Define tasks and crew&lt;/span&gt;
agent_centric_task = Task(
    description=(
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;Answer &#39;{customer_query}&#39;. First, search the PDFs using &#39;Search a PDF&#39;s content&#39; with {\&quot;query\&quot;: \&quot;&amp;lt;your search string&amp;gt;\&quot;}. Extract relevant passages and synthesise the answer.&quot;&lt;/span&gt;),
    tools=[pdf_search_tool, pdf_search_tool2, pdf_search_tool3],
    agent=agent_centric_agent
)

response_drafting_task = Task(
    description=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Use the gathered information to draft a comprehensive response to &#39;{customer_query}&#39;.&quot;&lt;/span&gt;,
    agent=agent_centric_agent,
    context=[agent_centric_task]
)

task_centric_crew = Crew(
    agents=[agent_centric_agent],
    tasks=[agent_centric_task, response_drafting_task],
    process=Process.sequential
)
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;7507&quot; data-start=&quot;7154&quot;&gt;The &lt;strong data-end=&quot;7175&quot; data-start=&quot;7158&quot;&gt;system prompt&lt;/strong&gt; instructs the agent to answer using only information from the PDFs, include citations, and avoid speculation.  We append a &lt;strong data-end=&quot;7321&quot; data-start=&quot;7299&quot;&gt;tool‑calling guide&lt;/strong&gt; that explicitly defines the JSON argument required by the &lt;code data-end=&quot;7395&quot; data-start=&quot;7380&quot;&gt;PDFSearchTool&lt;/code&gt;.  Without this guide the agent might call the tool incorrectly, causing the validation error described earlier.&lt;/p&gt;&lt;p data-end=&quot;7783&quot; data-start=&quot;7509&quot;&gt;The first task instructs the agent to search the PDFs for relevant text using a JSON query.  The second task uses the extracted passages to draft the final answer.  By assigning the PDF search tools only to the search task, we prevent accidental web queries during drafting.&lt;/p&gt;&lt;h2 data-end=&quot;7820&quot; data-start=&quot;7785&quot;&gt;Preparing for MiFID&amp;nbsp;III&lt;/h2&gt;&lt;p data-end=&quot;9451&quot; data-start=&quot;8642&quot;&gt;Our chatbot currently answers questions under MiFID&amp;nbsp;II and MiFIR.  However, regulatory evolution continues.  MiFID&amp;nbsp;III amendments were published in February&amp;nbsp;2024, entered into force in March&amp;nbsp;2024 and must be implemented by September&amp;nbsp;29&amp;nbsp;2025 (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=MiFID%20III%20follows%20a%20structured,compliance%20strategies%20with%20these%20milestones&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=MiFID%20III%20follows%20a%20structured,compliance%20strategies%20with%20these%20milestones&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  The third iteration does not overhaul the framework but raises the bar on surveillance and inducements: compliance teams must prepare for heightened expectations around off‑channel communications and record‑keeping (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=9%3A12&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=9%3A12&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  MiFID&amp;nbsp;III builds on MiFID&amp;nbsp;II by widening the focus to behavioural risks such as conflicts of interest and pricing opacity (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=communications%20that%20may%20lead%20to,auditable%20communications%20across%20all%20channels&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=communications%20that%20may%20lead%20to,auditable%20communications%20across%20all%20channels&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;, and regulators expect active monitoring rather than passive archiving (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=The%20foundational%20requirement%20to%20record,III%E2%80%94but%20regulators%20will%20expect%20more&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=The%20foundational%20requirement%20to%20record,III%E2%80%94but%20regulators%20will%20expect%20more&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;&lt;p data-end=&quot;9467&quot; data-start=&quot;9453&quot;&gt;To stay ahead:&lt;/p&gt;&lt;ul data-end=&quot;10554&quot; data-start=&quot;9469&quot;&gt;
&lt;li data-end=&quot;9648&quot; data-start=&quot;9469&quot;&gt;
&lt;p data-end=&quot;9648&quot; data-start=&quot;9471&quot;&gt;&lt;strong data-end=&quot;9509&quot; data-start=&quot;9471&quot;&gt;Integrate multi‑channel monitoring&lt;/strong&gt;: capture voice, chat, video and messaging across platforms; apply AI to detect misconduct patterns (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=2,requirements&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=2,requirements&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;9769&quot; data-start=&quot;9649&quot;&gt;
&lt;p data-end=&quot;9769&quot; data-start=&quot;9651&quot;&gt;&lt;strong data-end=&quot;9680&quot; data-start=&quot;9651&quot;&gt;Extend the knowledge base&lt;/strong&gt;: ingest ESMA Q&amp;amp;As, RTS documents and MiFID&amp;nbsp;III draft texts; update embeddings regularly.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;9932&quot; data-start=&quot;9770&quot;&gt;
&lt;p data-end=&quot;9932&quot; data-start=&quot;9772&quot;&gt;&lt;strong data-end=&quot;9799&quot; data-start=&quot;9772&quot;&gt;Use CrewAI’s guardrails&lt;/strong&gt;: implement output‑length checks or hallucination detection to ensure answers remain grounded (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Guardrails&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Guardrails&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;10132&quot; data-start=&quot;9933&quot;&gt;
&lt;p data-end=&quot;10132&quot; data-start=&quot;9935&quot;&gt;&lt;strong data-end=&quot;9959&quot; data-start=&quot;9935&quot;&gt;Leverage event buses&lt;/strong&gt; for audit logs and compliance evidence: CrewAI’s event bus emits events such as task started, tool use error, and LLM call completed (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=CrewAI%20now%20includes%20an%20event,the%20following%20events%20are%20emitted&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=CrewAI%20now%20includes%20an%20event,the%20following%20events%20are%20emitted&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;10369&quot; data-start=&quot;10133&quot;&gt;
&lt;p data-end=&quot;10369&quot; data-start=&quot;10135&quot;&gt;&lt;strong data-end=&quot;10160&quot; data-start=&quot;10135&quot;&gt;Adopt query rewriting&lt;/strong&gt; and &lt;em data-end=&quot;10178&quot; data-start=&quot;10165&quot;&gt;agentic RAG&lt;/em&gt; to improve retrieval.  CrewAI now supports query rewriting to focus on relevant keywords and integrates with vector databases like Qdrant and Weaviate (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Agentic%20RAG&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Agentic%20RAG&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;10554&quot; data-start=&quot;10370&quot;&gt;
&lt;p data-end=&quot;10554&quot; data-start=&quot;10372&quot;&gt;&lt;strong data-end=&quot;10394&quot; data-start=&quot;10372&quot;&gt;Plan for MiFID&amp;nbsp;III&lt;/strong&gt; deadlines: ensure your system can adapt to new PFOF bans, stricter inducement rules, and expanded communication capture (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=communications%20that%20may%20lead%20to,auditable%20communications%20across%20all%20channels&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=communications%20that%20may%20lead%20to,auditable%20communications%20across%20all%20channels&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;h2 data-end=&quot;10594&quot; data-start=&quot;10556&quot;&gt;Beyond Compliance – General Lessons&lt;/h2&gt;&lt;p data-end=&quot;10698&quot; data-start=&quot;10596&quot;&gt;While this capstone project addresses a specific regulatory domain, the design patterns are broadly applicable:&lt;/p&gt;&lt;ol data-end=&quot;11856&quot; data-start=&quot;10700&quot;&gt;
&lt;li data-end=&quot;10941&quot; data-start=&quot;10700&quot;&gt;
&lt;p data-end=&quot;10941&quot; data-start=&quot;10703&quot;&gt;&lt;strong data-end=&quot;10740&quot; data-start=&quot;10703&quot;&gt;Be explicit about tool signatures&lt;/strong&gt;: LLMs cannot infer parameter names; include examples and constraints in prompts.  For production systems, consider using structured tool calling (JSON Schema) or wrappers that handle input validation.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;11105&quot; data-start=&quot;10942&quot;&gt;
&lt;p data-end=&quot;11105&quot; data-start=&quot;10945&quot;&gt;&lt;strong data-end=&quot;10969&quot; data-start=&quot;10945&quot;&gt;Scope tools to tasks&lt;/strong&gt;: Minimises misuse and aids debugging.  For high‑impact domains (finance, healthcare) this can be critical for legal and safety reasons.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;11305&quot; data-start=&quot;11106&quot;&gt;
&lt;p data-end=&quot;11305&quot; data-start=&quot;11109&quot;&gt;&lt;strong data-end=&quot;11135&quot; data-start=&quot;11109&quot;&gt;Instrument your agents&lt;/strong&gt;: Use CrewAI’s event bus to collect telemetry on tool use and LLM calls.  This data helps debug issues and demonstrates compliance (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=CrewAI%20now%20includes%20an%20event,the%20following%20events%20are%20emitted&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=CrewAI%20now%20includes%20an%20event,the%20following%20events%20are%20emitted&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;11590&quot; data-start=&quot;11306&quot;&gt;
&lt;p data-end=&quot;11590&quot; data-start=&quot;11309&quot;&gt;&lt;strong data-end=&quot;11328&quot; data-start=&quot;11309&quot;&gt;Stay up to date&lt;/strong&gt;: Regulations change.  Regularly ingest new documents and search the web to supplement your knowledge base.  MiFID&amp;nbsp;III emphasises behaviour monitoring, so your system must adapt to detect tone and sentiment across channels (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=2,requirements&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://luware.com/blog/mifid-iii-a-compliance-guide-for-financial-businesses#:~:text=2,requirements&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;luware.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;11856&quot; data-start=&quot;11591&quot;&gt;
&lt;p data-end=&quot;11856&quot; data-start=&quot;11594&quot;&gt;&lt;strong data-end=&quot;11624&quot; data-start=&quot;11594&quot;&gt;Embrace guardrails and RAG&lt;/strong&gt;: Guardrails catch excessive or irrelevant outputs; agentic RAG (retrieval augmented generation) tailors the knowledge retrieval to each query, increasing precision and reducing hallucinations (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Agentic%20RAG&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Agentic%20RAG&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;h2 data-end=&quot;11871&quot; data-start=&quot;11858&quot;&gt;Conclusion&lt;/h2&gt;&lt;p data-end=&quot;12430&quot; data-start=&quot;11873&quot;&gt;By combining CrewAI’s multi‑agent orchestration with dedicated tools for PDF and web search, we built a robust MiFID&amp;nbsp;II compliance chatbot.  Assigning tools at the &lt;strong data-end=&quot;12045&quot; data-start=&quot;12037&quot;&gt;task&lt;/strong&gt; level rather than the &lt;strong data-end=&quot;12077&quot; data-start=&quot;12068&quot;&gt;agent&lt;/strong&gt; level yields more predictable and testable workflows.  The critical missing‑&lt;code data-end=&quot;12161&quot; data-start=&quot;12154&quot;&gt;query&lt;/code&gt; error was resolved by teaching the LLM to call tools correctly.  Looking ahead, MiFID&amp;nbsp;III will demand even greater surveillance and behavioural oversight; our modular architecture can adapt by adding new documents, query‑rewriting agents, guardrails and event logging.&lt;/p&gt;&lt;p data-end=&quot;2068&quot; data-start=&quot;1654&quot;&gt;




























&lt;/p&gt;&lt;p data-end=&quot;12881&quot; data-start=&quot;12432&quot;&gt;Agentic AI is evolving rapidly.  CrewAI’s adoption of the MCP, guardrails and event bus underscores this progress (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=MCP%20&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=MCP%20&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Guardrails&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=Guardrails&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=CrewAI%20now%20includes%20an%20event,the%20following%20events%20are%20emitted&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://blog.crewai.com/how-crewai-is-evolving-beyond-orchestration-to-create-the-most-powerful-agentic-ai-platform/#:~:text=CrewAI%20now%20includes%20an%20event,the%20following%20events%20are%20emitted&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;blog.crewai.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  With careful design, developers can harness these advances to build trustworthy, compliance‑ready chatbots that empower experts rather than replace them.  Start small, iterate quickly, and always validate your tools.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2025/10/building-mifid-iicompliance-chatbot.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKVOPmJuVHpPEhxkDQ2Sj6ingI7wZ0Ws9zVFQcLCDR1qkPnEy1-yP-g5giG3WC1Gw2GfjRj6UJphLVY275G07DoGmsBtye8REn3q7NhHc7hJ2GGAT2E5yRsxoqRPkZqJzMlIMNCREUFrWKvAzvH1mWTstt1u_jhcK8uhl-vk6mp3dt2ChWacW2azK5b34/s72-c/ChatGPT%20Image%20Oct%2010,%202025,%2007_11_05%20PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-8738696650963479179</guid><pubDate>Sat, 04 Oct 2025 19:04:00 +0000</pubDate><atom:updated>2026-03-15T21:42:17.275+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Compliance Automation</category><category domain="http://www.blogger.com/atom/ns#">Financial Regulation</category><category domain="http://www.blogger.com/atom/ns#">MiFID II/III Updates</category><category domain="http://www.blogger.com/atom/ns#">Multi-Agent AI (CrewAI)</category><category domain="http://www.blogger.com/atom/ns#">Near Real-Time Reporting</category><category domain="http://www.blogger.com/atom/ns#">PFOF Ban &amp; Consolidated Tape</category><title>Automating MiFID Compliance with CrewAI</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOr8-FWpQA-zYy0LaIni5kpGsvWvvr5pu0pAnfxR0W6DpjSKQTBURDXutYc5PPF013_tRLxzdjvLIinrNfwbd8yC7-ZyePvGFjHvJ3JM9Z_lU_rcMOlrbgPdl4ijPc70ah2pN1kUVP_TbRWKWkNr9NpP4U7YAOvE_h2l0RDgcj3tL_hQBfpgp42JRFG0U/s1024/59aa09fa-33f8-4483-a4f9-78c2723cdbdd.png&quot; style=&quot;display: inline; margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1024&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOr8-FWpQA-zYy0LaIni5kpGsvWvvr5pu0pAnfxR0W6DpjSKQTBURDXutYc5PPF013_tRLxzdjvLIinrNfwbd8yC7-ZyePvGFjHvJ3JM9Z_lU_rcMOlrbgPdl4ijPc70ah2pN1kUVP_TbRWKWkNr9NpP4U7YAOvE_h2l0RDgcj3tL_hQBfpgp42JRFG0U/s320/59aa09fa-33f8-4483-a4f9-78c2723cdbdd.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/h1&gt;&lt;p&gt;&lt;/p&gt;
&lt;div class=&quot;_tableContainer_1rjym_1&quot;&gt;&lt;div class=&quot;group _tableWrapper_1rjym_13 flex w-fit flex-col-reverse&quot; tabindex=&quot;-1&quot;&gt;&lt;table class=&quot;w-fit min-w-(--thread-content-width)&quot; data-end=&quot;2287&quot; data-start=&quot;43&quot;&gt;&lt;thead data-end=&quot;68&quot; data-start=&quot;43&quot;&gt;&lt;/thead&gt;&lt;tbody data-end=&quot;2287&quot; data-start=&quot;79&quot;&gt;&lt;tr data-end=&quot;618&quot; data-start=&quot;79&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;104&quot; data-start=&quot;79&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-col-size=&quot;xl&quot; data-end=&quot;618&quot; data-start=&quot;104&quot;&gt;&lt;strong data-end=&quot;103&quot; data-start=&quot;81&quot;&gt;Regulatory context&lt;/strong&gt;&lt;br /&gt;The MiFID II/III reviews introduce a single 7&amp;nbsp;% dark‑trading volume cap, ban payment for order flow (PFOF) and require Member States to ensure data‑quality standards for consolidated tape providers (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=In%20more%20detail%2C%20the%20Review%3A&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=In%20more%20detail%2C%20the%20Review%3A&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;legal.pwc.de&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  MiFID&amp;nbsp;III mandates extended data fields and near‑real‑time reporting by September&amp;nbsp;2025 (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=September%202025%20marks%20the%20deadline,authorities%20in%20near%20real%20time&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=September%202025%20marks%20the%20deadline,authorities%20in%20near%20real%20time&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  PFOF will be fully banned and a consolidated tape for equities, ETFs and derivatives will launch in June&amp;nbsp;2026 (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong data-end=&quot;638&quot; data-start=&quot;621&quot;&gt;Key deadlines&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;987&quot; data-start=&quot;619&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;639&quot; data-start=&quot;619&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-col-size=&quot;xl&quot; data-end=&quot;987&quot; data-start=&quot;639&quot;&gt;Member States must transpose the MiFID&amp;nbsp;II/MiFIR review into national law by 28&amp;nbsp;September&amp;nbsp;2025 (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=1,into%20force%20in%20late%202025&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=1,into%20force%20in%20late%202025&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;legal.pwc.de&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  September&amp;nbsp;2025 is also the deadline for MiFID&amp;nbsp;III reporting obligations (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=September%202025%20marks%20the%20deadline,authorities%20in%20near%20real%20time&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=September%202025%20marks%20the%20deadline,authorities%20in%20near%20real%20time&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;; the PFOF ban and consolidated tape come into force in June&amp;nbsp;2026 (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong data-end=&quot;1004&quot; data-start=&quot;990&quot;&gt;Challenges&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;1517&quot; data-start=&quot;988&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1005&quot; data-start=&quot;988&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-col-size=&quot;xl&quot; data-end=&quot;1517&quot; data-start=&quot;1005&quot;&gt;Firms face increased operational complexity: they must implement a single‑volume cap, monitor dark trading, ensure data quality for consolidated tapes and update policies and procedures (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;legal.pwc.de&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  Near‑real‑time reporting and expanded data fields demand modern IT infrastructure (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Extended%20reporting%20requirements%20and%20more,control%20by%20ESMA&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Extended%20reporting%20requirements%20and%20more,control%20by%20ESMA&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  All customer conversations across channels must be recorded and analysed for misconduct, requiring AI‑powered risk detection (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Impact%20on%20recording%20requirements&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Impact%20on%20recording%20requirements&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong data-end=&quot;1537&quot; data-start=&quot;1520&quot;&gt;Opportunities&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;1917&quot; data-start=&quot;1518&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1538&quot; data-start=&quot;1518&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-col-size=&quot;xl&quot; data-end=&quot;1917&quot; data-start=&quot;1538&quot;&gt;Greater transparency and harmonised data help investors and regulators.  The EU‑wide consolidated tape offers real‑time market data (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Kategorie%20MiFID%20II%20,for%20data%20and%20volume%20violations&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Kategorie%20MiFID%20II%20,for%20data%20and%20volume%20violations&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  AI and automation can transform compliance from a cost centre into a strategic differentiator: multi‑agent systems can handle large volumes of data, detect compliance risks and produce accessible reports.&lt;br /&gt;&lt;br /&gt;&lt;strong data-end=&quot;1943&quot; data-start=&quot;1920&quot;&gt;Automation approach&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;2287&quot; data-start=&quot;1918&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1944&quot; data-start=&quot;1918&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-col-size=&quot;xl&quot; data-end=&quot;2287&quot; data-start=&quot;1944&quot;&gt;CrewAI is a framework for building teams of autonomous agents that work together.  A research agent gathers the latest MiFID updates using web‑search tools and summarises them; a writer agent turns this research into an engaging blog post.  Tasks are executed sequentially, ensuring that the output of research feeds directly into writing.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 data-end=&quot;2316&quot; data-start=&quot;2289&quot;&gt;Why MiFID Updates Matter&lt;/h2&gt;
&lt;p data-end=&quot;2953&quot; data-start=&quot;2318&quot;&gt;MiFID&amp;nbsp;II was the EU’s flagship reform for securities markets.  Seven years after its introduction, financial markets look very different: algorithmic trading, retail investing apps and AI‑assisted research have become mainstream.  The European Commission therefore adopted a &lt;strong data-end=&quot;2618&quot; data-start=&quot;2593&quot;&gt;MiFID&amp;nbsp;II/MiFIR review&lt;/strong&gt; in February&amp;nbsp;2024.  The review aims to boost transparency and investor protection by removing redundant provisions, creating a consolidated tape and banning PFOF (payment&amp;nbsp; for order flow) (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=In%20more%20detail%2C%20the%20Review%3A&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=In%20more%20detail%2C%20the%20Review%3A&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;legal.pwc.de&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  Member States have until &lt;strong data-end=&quot;2867&quot; data-start=&quot;2846&quot;&gt;28&amp;nbsp;September&amp;nbsp;2025&lt;/strong&gt; to transpose the amendments into national law (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=1,into%20force%20in%20late%202025&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=1,into%20force%20in%20late%202025&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;legal.pwc.de&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p data-end=&quot;3509&quot; data-start=&quot;2955&quot;&gt;In parallel, the so‑called &lt;strong data-end=&quot;2995&quot; data-start=&quot;2982&quot;&gt;MiFID&amp;nbsp;III&lt;/strong&gt; package—an informal term for amendments to MiFID&amp;nbsp;II and MiFIR—modernises the rulebook to reflect digitalisation.  It requires firms to document transactions in greater detail and report them to supervisory authorities in near real time (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=September%202025%20marks%20the%20deadline,authorities%20in%20near%20real%20time&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=September%202025%20marks%20the%20deadline,authorities%20in%20near%20real%20time&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;), introduces a single 7&amp;nbsp;% dark‑trading cap (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Kategorie%20MiFID%20II%20,for%20data%20and%20volume%20violations&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Kategorie%20MiFID%20II%20,for%20data%20and%20volume%20violations&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;, bans PFOF (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt; and launches a consolidated tape for equities, ETFs and derivatives (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p data-end=&quot;3961&quot; data-start=&quot;3511&quot;&gt;These changes present both challenges and opportunities for financial institutions.  On the one hand, compliance will demand investments in data governance, monitoring tools and process redesign (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;legal.pwc.de&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  On the other hand, harmonised data and advanced analytics can enhance risk management and investor confidence.  Adopting &lt;strong data-end=&quot;3894&quot; data-start=&quot;3868&quot;&gt;multi‑agent AI systems&lt;/strong&gt; such as CrewAI can help firms navigate this landscape efficiently.&lt;/p&gt;
&lt;h2 data-end=&quot;4014&quot; data-start=&quot;3963&quot;&gt;Building a Multi‑Agent MiFID&amp;nbsp;Compliance Workflow&lt;/h2&gt;
&lt;p data-end=&quot;4358&quot; data-start=&quot;4016&quot;&gt;The traditional approach to regulatory change management involves human analysts reading lengthy legislative texts, summarising them and drafting internal or external communications.  This process is time‑consuming and error‑prone.  &lt;strong data-end=&quot;4259&quot; data-start=&quot;4249&quot;&gt;CrewAI&lt;/strong&gt; offers an alternative: you can orchestrate multiple AI agents to collaborate on complex workflows.&lt;/p&gt;
&lt;p data-end=&quot;4445&quot; data-start=&quot;4360&quot;&gt;Below is a high‑level example of how to automate MiFID&amp;nbsp;research and content creation:&lt;/p&gt;
&lt;ol data-end=&quot;5625&quot; data-start=&quot;4447&quot;&gt;
&lt;li data-end=&quot;4987&quot; data-start=&quot;4447&quot;&gt;
&lt;p data-end=&quot;4987&quot; data-start=&quot;4450&quot;&gt;&lt;strong data-end=&quot;4468&quot; data-start=&quot;4450&quot;&gt;Research agent&lt;/strong&gt; – A specialist agent queries real‑time web search tools (such as Serper) for the latest MiFID&amp;nbsp;II/III developments.  It extracts key facts—deadlines, major amendments, compliance obligations—and generates a structured report.  The report highlights the 28&amp;nbsp;September&amp;nbsp;2025 deadline for transposition (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=1,into%20force%20in%20late%202025&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://legal.pwc.de/en/news/articles/mifir-mifid-ii-review-making-sense-of-the-key-amendments#:~:text=1,into%20force%20in%20late%202025&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;legal.pwc.de&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;, the September&amp;nbsp;2025 start of near‑real‑time reporting (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=September%202025%20marks%20the%20deadline,authorities%20in%20near%20real%20time&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=September%202025%20marks%20the%20deadline,authorities%20in%20near%20real%20time&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;, and the June&amp;nbsp;2026 PFOF ban and consolidated tape (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=In%20June%202026%2C%20the%20PFOF,for%20routing%20customer%20orders%20there&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;5416&quot; data-start=&quot;4988&quot;&gt;
&lt;p data-end=&quot;5416&quot; data-start=&quot;4991&quot;&gt;&lt;strong data-end=&quot;5013&quot; data-start=&quot;4991&quot;&gt;Content strategist&lt;/strong&gt; – This agent receives the research report and crafts a reader‑friendly article.  It explains why the single‑volume cap and consolidated tape matter, discusses the pros and cons of the new regime, and includes practical advice for compliance teams.  It also emphasises how AI and automation can help firms handle increased data volumes and monitoring requirements (&lt;span data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Impact%20on%20recording%20requirements&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.asctechnologies.com/blog/post/mifid-iii-regulatory-changes-and-investor-protection-in-capital-markets/#:~:text=Impact%20on%20recording%20requirements&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;asctechnologies.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;5625&quot; data-start=&quot;5417&quot;&gt;
&lt;p data-end=&quot;5625&quot; data-start=&quot;5420&quot;&gt;&lt;strong data-end=&quot;5446&quot; data-start=&quot;5420&quot;&gt;Workflow orchestration&lt;/strong&gt; – A Crew object ties these agents and tasks together in a sequential process.  The research task must finish before the writing task begins, ensuring that the output is coherent.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-end=&quot;5652&quot; data-start=&quot;5627&quot;&gt;Sample Implementation&lt;/h3&gt;
&lt;p data-end=&quot;5881&quot; data-start=&quot;5654&quot;&gt;Below is a simplified Python script (see &lt;code data-end=&quot;5720&quot; data-start=&quot;5695&quot;&gt;&lt;a href=&quot;https://github.com/JordiCorbilla/langgraph-cookbook/tree/main/08%20-%20Mifid%20CrewAI%20Agent&quot;&gt;crewai_mifid_example.py&lt;/a&gt;&lt;/code&gt;) that demonstrates this workflow.  It uses the CrewAI framework and assumes you have set a valid Serper API key and configured a supported large language model.&lt;/p&gt;
&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;7606&quot; data-start=&quot;5883&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-python&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; os
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; crewai &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; Agent, Task, Crew, Process, LLM
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; crewai_tools &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; SerperDevTool

&lt;span class=&quot;hljs-comment&quot;&gt;# Set your Serper API key&lt;/span&gt;
os.environ[&lt;span class=&quot;hljs-string&quot;&gt;&#39;SERPER_API_KEY&#39;&lt;/span&gt;] = &lt;span class=&quot;hljs-string&quot;&gt;&#39;your_serper_api_key&#39;&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# Configure your LLM&lt;/span&gt;
llm = LLM(
    model=&lt;span class=&quot;hljs-string&quot;&gt;&quot;gtp-4&quot;&lt;/span&gt;,
    max_tokens=&lt;span class=&quot;hljs-number&quot;&gt;2000&lt;/span&gt;,
)

&lt;span class=&quot;hljs-comment&quot;&gt;# Define the research agent&lt;/span&gt;
research_agent = Agent(
    role=&lt;span class=&quot;hljs-string&quot;&gt;&quot;MiFID Research Analyst&quot;&lt;/span&gt;,
    goal=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Investigate and summarize recent MiFID II and III updates&quot;&lt;/span&gt;,
    backstory=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Expert in EU financial regulation&quot;&lt;/span&gt;,
    verbose=&lt;span class=&quot;hljs-literal&quot;&gt;True&lt;/span&gt;,
    allow_delegation=&lt;span class=&quot;hljs-literal&quot;&gt;False&lt;/span&gt;,
    llm=llm,
    tools=[SerperDevTool()],
)

&lt;span class=&quot;hljs-comment&quot;&gt;# Define the writer agent&lt;/span&gt;
writer_agent = Agent(
    role=&lt;span class=&quot;hljs-string&quot;&gt;&quot;RegTech Content Strategist&quot;&lt;/span&gt;,
    goal=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Write an engaging article about MiFID updates and AI compliance&quot;&lt;/span&gt;,
    backstory=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Skilled communicator for tech audiences&quot;&lt;/span&gt;,
    verbose=&lt;span class=&quot;hljs-literal&quot;&gt;True&lt;/span&gt;,
    allow_delegation=&lt;span class=&quot;hljs-literal&quot;&gt;True&lt;/span&gt;,
    llm=llm,
)

&lt;span class=&quot;hljs-comment&quot;&gt;# Define tasks&lt;/span&gt;
research_task = Task(
    description=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Gather and analyse MiFID II/III deadlines, reporting requirements and PFOF ban.&quot;&lt;/span&gt;,
    agent=research_agent,
    expected_output=&lt;span class=&quot;hljs-string&quot;&gt;&quot;A structured report on MiFID updates&quot;&lt;/span&gt;,
)
writer_task = Task(
    description=&lt;span class=&quot;hljs-string&quot;&gt;&quot;Draft a 4‑paragraph blog post based on the research.&quot;&lt;/span&gt;,
    agent=writer_agent,
    expected_output=&lt;span class=&quot;hljs-string&quot;&gt;&quot;A blog post summarising MiFID updates and the role of AI in compliance.&quot;&lt;/span&gt;,
)

crew = Crew(
    agents=[research_agent, writer_agent],
    tasks=[research_task, writer_task],
    process=Process.sequential,
    verbose=&lt;span class=&quot;hljs-literal&quot;&gt;True&lt;/span&gt;,
)

&lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; __name__ == &lt;span class=&quot;hljs-string&quot;&gt;&#39;__main__&#39;&lt;/span&gt;:
    result = crew.kickoff(inputs={&lt;span class=&quot;hljs-string&quot;&gt;&#39;topic&#39;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&#39;MiFID II and MiFID III updates 2025&#39;&lt;/span&gt;})
    &lt;span class=&quot;hljs-built_in&quot;&gt;print&lt;/span&gt;(result)
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;h3 data-end=&quot;7667&quot; data-start=&quot;7608&quot;&gt;Pros and Cons of Using CrewAI for Regulatory Compliance&lt;/h3&gt;
&lt;ul data-end=&quot;8950&quot; data-start=&quot;7669&quot;&gt;
&lt;li data-end=&quot;8321&quot; data-start=&quot;7669&quot;&gt;
&lt;p data-end=&quot;7679&quot; data-start=&quot;7671&quot;&gt;&lt;strong data-end=&quot;7679&quot; data-start=&quot;7671&quot;&gt;Pros&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;8321&quot; data-start=&quot;7682&quot;&gt;
&lt;li data-end=&quot;7867&quot; data-start=&quot;7682&quot;&gt;
&lt;p data-end=&quot;7867&quot; data-start=&quot;7684&quot;&gt;&lt;em data-end=&quot;7706&quot; data-start=&quot;7684&quot;&gt;Efficiency and scale&lt;/em&gt;: AI agents can monitor regulatory updates 24/7, quickly summarising amendments like the MiFID reviews.  This reduces manual labour and speeds up response times.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;7993&quot; data-start=&quot;7870&quot;&gt;
&lt;p data-end=&quot;7993&quot; data-start=&quot;7872&quot;&gt;&lt;em data-end=&quot;7885&quot; data-start=&quot;7872&quot;&gt;Consistency&lt;/em&gt;: Automated pipelines deliver uniform analysis and writing quality, avoiding variability in human reporting.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;8159&quot; data-start=&quot;7996&quot;&gt;
&lt;p data-end=&quot;8159&quot; data-start=&quot;7998&quot;&gt;&lt;em data-end=&quot;8012&quot; data-start=&quot;7998&quot;&gt;Adaptability&lt;/em&gt;: Changing the topic (e.g., from MiFID to ESG or AI regulation) simply requires passing a different input string; no need to redesign the workflow.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;8321&quot; data-start=&quot;8162&quot;&gt;
&lt;p data-end=&quot;8321&quot; data-start=&quot;8164&quot;&gt;&lt;em data-end=&quot;8183&quot; data-start=&quot;8164&quot;&gt;Integrative power&lt;/em&gt;: Agents can be equipped with multiple tools—web search, document parsing, API connectors—allowing them to pull data from diverse sources.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;8950&quot; data-start=&quot;8323&quot;&gt;
&lt;p data-end=&quot;8333&quot; data-start=&quot;8325&quot;&gt;&lt;strong data-end=&quot;8333&quot; data-start=&quot;8325&quot;&gt;Cons&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;8950&quot; data-start=&quot;8336&quot;&gt;
&lt;li data-end=&quot;8488&quot; data-start=&quot;8336&quot;&gt;
&lt;p data-end=&quot;8488&quot; data-start=&quot;8338&quot;&gt;&lt;em data-end=&quot;8359&quot; data-start=&quot;8338&quot;&gt;Context limitations&lt;/em&gt;: AI models may misinterpret nuanced legal language or miss implicit regulatory interactions.  Human oversight remains essential.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;8637&quot; data-start=&quot;8491&quot;&gt;
&lt;p data-end=&quot;8637&quot; data-start=&quot;8493&quot;&gt;&lt;em data-end=&quot;8518&quot; data-start=&quot;8493&quot;&gt;Data‑source constraints&lt;/em&gt;: Tools like Serper rely on publicly available information.  Some proprietary regulatory databases may be inaccessible.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;8764&quot; data-start=&quot;8640&quot;&gt;
&lt;p data-end=&quot;8764&quot; data-start=&quot;8642&quot;&gt;&lt;em data-end=&quot;8657&quot; data-start=&quot;8642&quot;&gt;Initial setup&lt;/em&gt;: Configuring secure LLM access and API keys requires careful attention to privacy and compliance policies.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;8950&quot; data-start=&quot;8767&quot;&gt;
&lt;p data-end=&quot;8950&quot; data-start=&quot;8769&quot;&gt;&lt;em data-end=&quot;8791&quot; data-start=&quot;8769&quot;&gt;Regulatory liability&lt;/em&gt;: Over‑reliance on automated interpretations could pose risks if the system outputs incorrect advice.  Always validate AI‑generated content with legal experts.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-end=&quot;8972&quot; data-start=&quot;8952&quot;&gt;Conda Environment&lt;/h2&gt;
&lt;p data-end=&quot;9110&quot; data-start=&quot;8974&quot;&gt;To reproduce the workflow locally, create a &lt;strong data-end=&quot;9039&quot; data-start=&quot;9018&quot;&gt;conda environment&lt;/strong&gt; named&amp;nbsp;&lt;code data-end=&quot;9052&quot; data-start=&quot;9046&quot;&gt;crew&lt;/code&gt; with the following specification (see &lt;code data-end=&quot;9108&quot; data-start=&quot;9091&quot;&gt;environment.yml&lt;/code&gt;):&lt;/p&gt;
&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;9415&quot; data-start=&quot;9112&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;crew&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;channels:&lt;/span&gt;
  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;defaults&lt;/span&gt;
  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;conda-forge&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;dependencies:&lt;/span&gt;
  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;python=3.10&lt;/span&gt;
  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;pip&lt;/span&gt;
  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;pip:&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;crewai==0.193.2&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;crewai-tools==0.38.0&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;langchain==0.3.20&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;langchain-community==0.3.19&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;databricks-sdk==0.57.0&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;jupyter&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ipykernel&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;openai&lt;/span&gt;
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p data-end=&quot;9445&quot; data-start=&quot;9417&quot;&gt;Create the environment with:&lt;/p&gt;
&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;9514&quot; data-start=&quot;9447&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-bash&quot;&gt;conda &lt;span class=&quot;hljs-built_in&quot;&gt;env&lt;/span&gt; create -f environment.yml
conda activate crew
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p data-end=&quot;9621&quot; data-start=&quot;9516&quot;&gt;Install any additional models or API keys (e.g., for Serper or your chosen LLM) as environment variables.&lt;/p&gt;
&lt;h2 data-end=&quot;9650&quot; data-start=&quot;9623&quot;&gt;Final Thoughts&lt;/h2&gt;
&lt;p data-end=&quot;10466&quot; data-start=&quot;10085&quot;&gt;The MiFID II/MiFIR review and the forthcoming MiFID&amp;nbsp;III rules represent the biggest shake‑up of EU securities regulation since 2018.  Firms must prepare for tighter reporting timelines, a 7&amp;nbsp;% dark‑trading cap and the end of PFOF.  At the same time, greater transparency and harmonised data open new opportunities for data‑driven trading strategies and improved investor protection.&lt;/p&gt;
&lt;p data-end=&quot;10874&quot; data-start=&quot;10468&quot;&gt;Leveraging frameworks like &lt;strong data-end=&quot;10505&quot; data-start=&quot;10495&quot;&gt;CrewAI&lt;/strong&gt; allows compliance teams to automate the tedious parts of regulatory change management.  By delegating research and writing tasks to specialised agents, practitioners can focus on high‑level analysis and strategic decision‑making.  As always, technology is a tool—not a substitute for legal judgement—but used wisely it can turn regulation into a competitive advantage.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2025/10/automating-mifid-compliance-with-crewai.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOr8-FWpQA-zYy0LaIni5kpGsvWvvr5pu0pAnfxR0W6DpjSKQTBURDXutYc5PPF013_tRLxzdjvLIinrNfwbd8yC7-ZyePvGFjHvJ3JM9Z_lU_rcMOlrbgPdl4ijPc70ah2pN1kUVP_TbRWKWkNr9NpP4U7YAOvE_h2l0RDgcj3tL_hQBfpgp42JRFG0U/s72-c/59aa09fa-33f8-4483-a4f9-78c2723cdbdd.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>London, UK</georss:featurename><georss:point>51.5072178 -0.1275862</georss:point><georss:box>23.196983963821154 -35.2838362 79.817451636178845 35.0286638</georss:box></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7022755517551007355.post-2904676072726619968</guid><pubDate>Sun, 28 Sep 2025 18:14:00 +0000</pubDate><atom:updated>2025-09-28T18:14:08.949+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AI workflow</category><category domain="http://www.blogger.com/atom/ns#">dynamic portfolio</category><category domain="http://www.blogger.com/atom/ns#">fictional personas</category><category domain="http://www.blogger.com/atom/ns#">investment advisor</category><category domain="http://www.blogger.com/atom/ns#">investment strategies</category><category domain="http://www.blogger.com/atom/ns#">LLM integration</category><category domain="http://www.blogger.com/atom/ns#">orchestrator-worker pattern</category><category domain="http://www.blogger.com/atom/ns#">reflection pattern</category><category domain="http://www.blogger.com/atom/ns#">risk grades</category><title>Reflection Pattern for Investment Advisory: A Fictional Take</title><description>&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOt6jmB2FyPTB8Xb-m6aO1etGbOAhQzU2I-XUOClZEgjEEWJbVq47-r0URqC5IjkSucUxHHGqJB4bf0s2u-tUvDDdj4LOYlST5yYZw5UMIWgNYRdKKmT2X4oZ_mnsaDp7-R9TsxgNc3XiJjJfPFRlihWNnHb9qgQywVtOM41v9FZ5tyJEESFgT1583O2Q/s1024/fe69c127-4310-47ee-8e47-436d8fd58eb1.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; display: inline !important; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1024&quot; data-original-width=&quot;1024&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOt6jmB2FyPTB8Xb-m6aO1etGbOAhQzU2I-XUOClZEgjEEWJbVq47-r0URqC5IjkSucUxHHGqJB4bf0s2u-tUvDDdj4LOYlST5yYZw5UMIWgNYRdKKmT2X4oZ_mnsaDp7-R9TsxgNc3XiJjJfPFRlihWNnHb9qgQywVtOM41v9FZ5tyJEESFgT1583O2Q/w320-h320/fe69c127-4310-47ee-8e47-436d8fd58eb1.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h1 style=&quot;text-align: left;&quot;&gt;Reflection Pattern for Investment Advisory: A Fictional Take&lt;/h1&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;This article explores how the &lt;strong data-end=&quot;572&quot; data-start=&quot;550&quot;&gt;reflection pattern,&amp;nbsp;&lt;/strong&gt;an &lt;b&gt;agentic AI &lt;/b&gt;design pattern in which a model iteratively generates, critiques and refines its own work, can be applied to investment advisory.  We’ll introduce fictional superstar advisors inspired by pop culture, explain how the reflection loop fits within an &lt;strong data-end=&quot;857&quot; data-start=&quot;834&quot;&gt;orchestrator–worker&lt;/strong&gt; architecture, and provide a full Python implementation.  Along the way, we highlight benefits, drawbacks and speculative future applications.&lt;/p&gt;&lt;h2 data-end=&quot;86&quot; data-start=&quot;64&quot;&gt;Summary at a Glance&lt;/h2&gt;&lt;p&gt;
&lt;/p&gt;&lt;div class=&quot;_tableContainer_1rjym_1&quot;&gt;&lt;div class=&quot;group _tableWrapper_1rjym_13 flex w-fit flex-col-reverse&quot; tabindex=&quot;-1&quot;&gt;&lt;table class=&quot;w-fit min-w-(--thread-content-width)&quot; data-end=&quot;518&quot; data-start=&quot;88&quot;&gt;&lt;thead data-end=&quot;176&quot; data-start=&quot;88&quot;&gt;&lt;tr data-end=&quot;176&quot; data-start=&quot;88&quot;&gt;&lt;th data-col-size=&quot;sm&quot; data-end=&quot;98&quot; data-start=&quot;88&quot;&gt;Persona&lt;/th&gt;&lt;th data-col-size=&quot;md&quot; data-end=&quot;106&quot; data-start=&quot;98&quot;&gt;Style&lt;/th&gt;&lt;th data-col-size=&quot;md&quot; data-end=&quot;176&quot; data-start=&quot;106&quot;&gt;Typical Allocation (Equities / Alternatives / Fixed‑Income / Cash)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody data-end=&quot;518&quot; data-start=&quot;191&quot;&gt;&lt;tr data-end=&quot;294&quot; data-start=&quot;191&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;211&quot; data-start=&quot;191&quot;&gt;&lt;strong data-end=&quot;210&quot; data-start=&quot;193&quot;&gt;Bobby Axelrod&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;271&quot; data-start=&quot;211&quot;&gt;Aggressive hedge‑fund maverick willing to ride volatility&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;294&quot; data-start=&quot;271&quot;&gt;70% / 20% / 5% / 5%&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;402&quot; data-start=&quot;295&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;314&quot; data-start=&quot;295&quot;&gt;&lt;strong data-end=&quot;313&quot; data-start=&quot;297&quot;&gt;Gordon Gekko&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;379&quot; data-start=&quot;314&quot;&gt;Opportunistic raider who loves leverage, options and arbitrage&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;402&quot; data-start=&quot;379&quot;&gt;75% / 15% / 5% / 5%&lt;/td&gt;&lt;/tr&gt;&lt;tr data-end=&quot;518&quot; data-start=&quot;403&quot;&gt;&lt;td data-col-size=&quot;sm&quot; data-end=&quot;421&quot; data-start=&quot;403&quot;&gt;&lt;strong data-end=&quot;420&quot; data-start=&quot;405&quot;&gt;Richie&amp;nbsp;Rich&lt;/strong&gt;&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;482&quot; data-start=&quot;421&quot;&gt;Cautious wealth‑preserver who favours blue chips and bonds&lt;/td&gt;&lt;td data-col-size=&quot;md&quot; data-end=&quot;518&quot; data-start=&quot;482&quot;&gt;30–60% / 10–20% / 15–45% / 5–15%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 data-end=&quot;1036&quot; data-start=&quot;1001&quot;&gt;The Reflection Pattern Explained&lt;/h2&gt;&lt;p data-end=&quot;1855&quot; data-start=&quot;1038&quot;&gt;The reflection pattern originates in cognitive science and has recently been adopted for large language models (LLMs).  The idea is simple yet powerful: rather than trusting a single draft, the model runs a &lt;strong data-end=&quot;1273&quot; data-start=&quot;1245&quot;&gt;generate–critique–refine&lt;/strong&gt; loop.  According to Analytics&amp;nbsp;Vidhya, the pattern “is a method where the model generates, critiques and refines its outputs through an iterative self‑assessment process” (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=Overview&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=Overview&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  This loop mimics human editing, catching mistakes, clarifying ambiguities and improving quality across multiple passes (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=Overview&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=Overview&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  A second LLM (or the same model with a different prompt) acts as a &lt;b&gt;critic&lt;/b&gt;, evaluating the initial output against well‑defined criteria and feeding feedback back to the generator (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.philschmid.de/agentic-pattern#:~:text=Reflection%20Pattern&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.philschmid.de/agentic-pattern#:~:text=Reflection%20Pattern&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;philschmid.de&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;&lt;p data-end=&quot;1901&quot; data-start=&quot;1857&quot;&gt;Key steps in the reflection pattern include:&lt;/p&gt;&lt;ol data-end=&quot;2618&quot; data-start=&quot;1903&quot;&gt;
&lt;li data-end=&quot;2090&quot; data-start=&quot;1903&quot;&gt;
&lt;p data-end=&quot;2090&quot; data-start=&quot;1906&quot;&gt;&lt;strong data-end=&quot;1921&quot; data-start=&quot;1906&quot;&gt;Generation:&lt;/strong&gt; produce a first draft based on the user’s prompt.  This can be done in a zero‑shot manner, generating a candidate without examples (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=1&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=1&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2263&quot; data-start=&quot;2091&quot;&gt;
&lt;p data-end=&quot;2263&quot; data-start=&quot;2094&quot;&gt;&lt;strong data-end=&quot;2114&quot; data-start=&quot;2094&quot;&gt;Self‑reflection:&lt;/strong&gt; the model reviews its own work, identifies errors, missing details or stylistic issues, and generates feedback (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=The%20reflection%20step%20is%20a,This%20step%20involves&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=The%20reflection%20step%20is%20a,This%20step%20involves&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2618&quot; data-start=&quot;2264&quot;&gt;
&lt;p data-end=&quot;2618&quot; data-start=&quot;2267&quot;&gt;&lt;strong data-end=&quot;2294&quot; data-start=&quot;2267&quot;&gt;Iteration &amp;amp; refinement:&lt;/strong&gt; the feedback is incorporated into a new draft, and the cycle repeats until the output &lt;u&gt;meets quality thresholds&lt;/u&gt; or a maximum number of iterations is reached (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://tpiros.dev/blog/building-with-reflection-a-practical-agentic-ai-workflow/#:~:text=The%20Reflection%20Loop%20Pattern&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://tpiros.dev/blog/building-with-reflection-a-practical-agentic-ai-workflow/#:~:text=The%20Reflection%20Loop%20Pattern&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;tpiros.dev&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;).&amp;nbsp; Stopping conditions prevent infinite loops and include quality targets or iteration limits (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=,loops%20in%20the%20reflection%20process&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=,loops%20in%20the%20reflection%20process&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p data-end=&quot;3040&quot; data-start=&quot;2620&quot;&gt;Practical applications of the reflection pattern include code generation, content drafting, data analysis and decision‑making.  Because the model critiques itself, it can catch inconsistencies and gradually improve the output.  However, iterative generation consumes time and compute, and repeated prompts can induce drift or hallucination.  A disciplined stopping criterion and robust evaluation criteria are essential.&lt;/p&gt;&lt;h2 data-end=&quot;3076&quot; data-start=&quot;3042&quot;&gt;The Orchestrator–Worker Pattern&lt;/h2&gt;&lt;p data-end=&quot;3606&quot; data-start=&quot;3078&quot;&gt;The reflection loop fits naturally into an &lt;strong data-end=&quot;3157&quot; data-start=&quot;3121&quot;&gt;orchestrator–worker architecture&lt;/strong&gt;, another agentic design pattern.  In this setup, a central orchestrator decomposes a complex task into subtasks and dispatches them to specialized worker agents.  The orchestrator maintains global oversight, monitors worker performance and synthesizes partial results into a final answer (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://dzone.com/articles/ai-agent-architectures-patterns-applications-guide#:~:text=1.%20Orchestrator&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://dzone.com/articles/ai-agent-architectures-patterns-applications-guide#:~:text=1.%20Orchestrator&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;dzone.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  Workers operate as domain‑specific experts, focusing solely on their assigned tasks (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://dzone.com/articles/ai-agent-architectures-patterns-applications-guide#:~:text=1.%20Orchestrator&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://dzone.com/articles/ai-agent-architectures-patterns-applications-guide#:~:text=1.%20Orchestrator&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;dzone.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;&lt;p data-end=&quot;3660&quot; data-start=&quot;3608&quot;&gt;This separation of concerns brings several benefits:&lt;/p&gt;&lt;ul data-end=&quot;4243&quot; data-start=&quot;3662&quot;&gt;
&lt;li data-end=&quot;3790&quot; data-start=&quot;3662&quot;&gt;
&lt;p data-end=&quot;3790&quot; data-start=&quot;3664&quot;&gt;&lt;strong data-end=&quot;3695&quot; data-start=&quot;3664&quot;&gt;Modularity &amp;amp; extensibility:&lt;/strong&gt; new worker agents can be added without rewriting the orchestrator, making the system scalable.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;3880&quot; data-start=&quot;3791&quot;&gt;
&lt;p data-end=&quot;3880&quot; data-start=&quot;3793&quot;&gt;&lt;strong data-end=&quot;3809&quot; data-start=&quot;3793&quot;&gt;Parallelism:&lt;/strong&gt; tasks can run concurrently, reducing latency and improving throughput.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4039&quot; data-start=&quot;3881&quot;&gt;
&lt;p data-end=&quot;4039&quot; data-start=&quot;3883&quot;&gt;&lt;strong data-end=&quot;3898&quot; data-start=&quot;3883&quot;&gt;Resilience:&lt;/strong&gt; if one worker fails, the orchestrator can still produce a meaningful result from the remaining outputs (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://pytrick.medium.com/agentic-ai-design-pattern-orchestrator-worker-6d76ffc09f0c#:~:text=Think%20of%20the%20Orchestrator%20as,manager%20and%20Workers%20as%20specialists&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://pytrick.medium.com/agentic-ai-design-pattern-orchestrator-worker-6d76ffc09f0c#:~:text=Think%20of%20the%20Orchestrator%20as,manager%20and%20Workers%20as%20specialists&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;pytrick.medium.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;4243&quot; data-start=&quot;4040&quot;&gt;
&lt;p data-end=&quot;4243&quot; data-start=&quot;4042&quot;&gt;&lt;strong data-end=&quot;4062&quot; data-start=&quot;4042&quot;&gt;Central control:&lt;/strong&gt; centralized monitoring ensures that quality standards are enforced across workers and that fallback strategies are applied when errors occur (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://dzone.com/articles/ai-agent-architectures-patterns-applications-guide#:~:text=1.%20Orchestrator&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://dzone.com/articles/ai-agent-architectures-patterns-applications-guide#:~:text=1.%20Orchestrator&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;dzone.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p data-end=&quot;4880&quot; data-start=&quot;4245&quot;&gt;The orchestrator–worker pattern is particularly useful for workflows that combine planning, data retrieval, analysis and synthesis.  For example, in a technical stock analysis system, an orchestrator fetches data once, sends it to workers computing RSI, MACD and other indicators, then aggregates the signals into a report (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://pytrick.medium.com/agentic-ai-design-pattern-orchestrator-worker-6d76ffc09f0c#:~:text=Think%20of%20the%20Orchestrator%20as,manager%20and%20Workers%20as%20specialists&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://pytrick.medium.com/agentic-ai-design-pattern-orchestrator-worker-6d76ffc09f0c#:~:text=Think%20of%20the%20Orchestrator%20as,manager%20and%20Workers%20as%20specialists&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;pytrick.medium.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.  Our fictional investment advisor will reuse this structure: the orchestrator iterates through different personas (workers), each generating an investment plan; an evaluator agent critiques the plan; and the orchestrator decides whether to accept or request another draft.&lt;/p&gt;&lt;h2 data-end=&quot;4916&quot; data-start=&quot;4882&quot;&gt;Fictional Investment Superstars&lt;/h2&gt;&lt;p data-end=&quot;5201&quot; data-start=&quot;4918&quot;&gt;Real investment icons like Cathie&amp;nbsp;Wood or Warren&amp;nbsp;Buffett offer recognisable strategies, but they also introduce brand‑specific bias.  To avoid conflating advice with real identities, and to show that agentic workflows can model a variety of styles, we propose three fictional personas:&lt;/p&gt;&lt;ul data-end=&quot;6007&quot; data-start=&quot;5203&quot;&gt;
&lt;li data-end=&quot;5494&quot; data-start=&quot;5203&quot;&gt;
&lt;p data-end=&quot;5494&quot; data-start=&quot;5205&quot;&gt;&lt;strong data-end=&quot;5223&quot; data-start=&quot;5205&quot;&gt;Bobby&amp;nbsp;Axelrod:&lt;/strong&gt; loosely modelled on a hedge‑fund manager character.  Bobby favours high‑growth sectors and alternative assets.  In our template he allocates ~70 % to equities and 20 % to alternatives, leaving minimal fixed income and cash.  This results in an &lt;strong data-end=&quot;5482&quot; data-start=&quot;5468&quot;&gt;aggressive&lt;/strong&gt; risk grade.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;5761&quot; data-start=&quot;5495&quot;&gt;
&lt;p data-end=&quot;5761&quot; data-start=&quot;5497&quot;&gt;&lt;strong data-end=&quot;5514&quot; data-start=&quot;5497&quot;&gt;Gordon&amp;nbsp;Gekko:&lt;/strong&gt; inspired by the 1980s corporate raider, Gordon prioritises concentrated bets, options and arbitrage.  He rarely recommends conservative portfolios, pushing equities to 75 % and leaving a token 5 % to fixed income.  Another &lt;strong data-end=&quot;5752&quot; data-start=&quot;5738&quot;&gt;aggressive&lt;/strong&gt; profile.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;6007&quot; data-start=&quot;5762&quot;&gt;
&lt;p data-end=&quot;6007&quot; data-start=&quot;5764&quot;&gt;&lt;strong data-end=&quot;5780&quot; data-start=&quot;5764&quot;&gt;Richie&amp;nbsp;Rich:&lt;/strong&gt; a wealthy heir who values security.  Richie’s allocation varies by target grade: 60–30 % equities, 10–20 % alternatives, 15–45 % fixed income and the rest cash.  He can satisfy &lt;strong data-end=&quot;5974&quot; data-start=&quot;5958&quot;&gt;conservative&lt;/strong&gt; or &lt;strong data-end=&quot;5990&quot; data-start=&quot;5978&quot;&gt;moderate&lt;/strong&gt; risk tolerances.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p data-end=&quot;6470&quot; data-start=&quot;6009&quot;&gt;These personas serve as “workers” in our orchestrator.  They each provide a distinct draft plan based on the investor’s profile and desired risk grade.  A simple evaluator reads the plan, calculates the equity allocation and assigns a risk grade (conservative, moderate or aggressive).  If the assigned grade doesn’t match the target, the orchestrator calls another persona to propose a new plan.  After a preset number of iterations, the best plan is returned.&lt;/p&gt;&lt;h2 data-end=&quot;6505&quot; data-start=&quot;6472&quot;&gt;LLM Integration with LangChain&lt;/h2&gt;&lt;p data-end=&quot;7204&quot; data-start=&quot;6507&quot;&gt;While deterministic templates offer repeatable outputs, they lack the spontaneity and nuance of natural language generation.  To make the advisor more generative and human‑like, the latest version integrates an optional language model using &lt;strong data-end=&quot;6774&quot; data-start=&quot;6748&quot;&gt;LangChain’s ChatOpenAI&lt;/strong&gt; interface.  At the top of the code we attempt to import &lt;code data-end=&quot;6843&quot; data-start=&quot;6831&quot;&gt;ChatOpenAI&lt;/code&gt; and &lt;code data-end=&quot;6868&quot; data-start=&quot;6848&quot;&gt;ChatPromptTemplate&lt;/code&gt;.  A helper function &lt;code data-end=&quot;6900&quot; data-start=&quot;6889&quot;&gt;get_llm()&lt;/code&gt; tries to instantiate a &lt;strong data-end=&quot;6939&quot; data-start=&quot;6924&quot;&gt;gpt‑4o‑mini&lt;/strong&gt; model with a moderate temperature (0.7).  When this succeeds, each persona constructs a structured prompt containing the investor’s profile and target grade; the model then generates a bespoke Markdown plan with asset allocations, rationale and rebalancing advice.&lt;/p&gt;&lt;p data-end=&quot;7717&quot; data-start=&quot;7206&quot;&gt;The beauty of this design is its &lt;strong data-end=&quot;7260&quot; data-start=&quot;7239&quot;&gt;graceful fallback&lt;/strong&gt;: if LangChain isn’t installed or the model fails to initialize (for instance, due to missing API keys), the code reverts to deterministic templates.  The reflection loop and evaluator remain unchanged, so the orchestrator–worker architecture stays intact.  Only the plan generation mechanism becomes dynamic when an LLM is available.  This modularity demonstrates how real‑world systems can incrementally adopt generative AI without sacrificing robustness.&lt;/p&gt;&lt;h3 data-end=&quot;7742&quot; data-start=&quot;7719&quot;&gt;Code Implementation&lt;/h3&gt;&lt;p data-end=&quot;8201&quot; data-start=&quot;7744&quot;&gt;To put these ideas into practice, we provide a fully working Python module that mirrors the reflection loop described in the Skills&amp;nbsp;Network lab while swapping the real investors for our fictional superstars.  The module defines a shared &lt;strong data-end=&quot;7990&quot; data-start=&quot;7981&quot;&gt;state&lt;/strong&gt; dictionary, prompts for each persona, an evaluator inspired by Richie&amp;nbsp;Rich’s prudence, and a simple Python loop that iteratively generates and critiques investment plans until the risk grade matches the target.&lt;/p&gt;&lt;p data-end=&quot;8226&quot; data-start=&quot;8203&quot;&gt;Key components include:&lt;/p&gt;&lt;ul data-end=&quot;9004&quot; data-start=&quot;8228&quot;&gt;
&lt;li data-end=&quot;8343&quot; data-start=&quot;8228&quot;&gt;
&lt;p data-end=&quot;8343&quot; data-start=&quot;8230&quot;&gt;&lt;strong data-end=&quot;8258&quot; data-start=&quot;8230&quot;&gt;&lt;code data-end=&quot;8256&quot; data-start=&quot;8232&quot;&gt;determine_target_grade&lt;/code&gt;&lt;/strong&gt; – uses an LLM to pick a suitable risk grade for the investor based on their profile.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;8502&quot; data-start=&quot;8344&quot;&gt;
&lt;p data-end=&quot;8502&quot; data-start=&quot;8346&quot;&gt;&lt;strong data-end=&quot;8377&quot; data-start=&quot;8346&quot;&gt;&lt;code data-end=&quot;8375&quot; data-start=&quot;8348&quot;&gt;investment_plan_generator&lt;/code&gt;&lt;/strong&gt; – produces an initial Bobby&amp;nbsp;Axelrod–style plan and refines it using Gordon&amp;nbsp;Gekko’s opportunistic rules when feedback exists.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;8667&quot; data-start=&quot;8503&quot;&gt;
&lt;p data-end=&quot;8667&quot; data-start=&quot;8505&quot;&gt;&lt;strong data-end=&quot;8524&quot; data-start=&quot;8505&quot;&gt;&lt;code data-end=&quot;8522&quot; data-start=&quot;8507&quot;&gt;evaluate_plan&lt;/code&gt;&lt;/strong&gt; – calls a Richie&amp;nbsp;Rich–style evaluator to classify the risk level and provide feedback on diversification, volatility and capital preservation.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;8804&quot; data-start=&quot;8668&quot;&gt;
&lt;p data-end=&quot;8804&quot; data-start=&quot;8670&quot;&gt;&lt;strong data-end=&quot;8692&quot; data-start=&quot;8670&quot;&gt;&lt;code data-end=&quot;8690&quot; data-start=&quot;8672&quot;&gt;route_investment&lt;/code&gt;&lt;/strong&gt; – decides whether to accept the current plan or request another iteration, enforcing a maximum number of loops.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;9004&quot; data-start=&quot;8805&quot;&gt;
&lt;p data-end=&quot;9004&quot; data-start=&quot;8807&quot;&gt;&lt;strong data-end=&quot;8836&quot; data-start=&quot;8807&quot;&gt;&lt;code data-end=&quot;8834&quot; data-start=&quot;8809&quot;&gt;run_reflection_workflow&lt;/code&gt;&lt;/strong&gt; – orchestrates the entire generate–evaluate–route cycle in plain Python without relying on LangGraph, returning the final plan along with feedback and iteration count.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p data-end=&quot;9098&quot; data-start=&quot;9006&quot;&gt;Here is a high‑level sketch of the module’s structure (see&amp;nbsp;&lt;a href=&quot;https://github.com/JordiCorbilla/langgraph-cookbook/tree/main/06%20-%20Investment%20Agent&quot;&gt;langgraph-cookbook/06 - Investment Agent at main · JordiCorbilla/langgraph-cookbook&lt;/a&gt;&amp;nbsp;for complete code):&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;10435&quot; data-start=&quot;9100&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-python&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; typing &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; TypedDict, &lt;span class=&quot;hljs-type&quot;&gt;Dict&lt;/span&gt;, &lt;span class=&quot;hljs-type&quot;&gt;Literal&lt;/span&gt;, Annotated
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; langchain_openai &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; ChatOpenAI
&lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; langchain_core.prompts &lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; ChatPromptTemplate

grades = &lt;span class=&quot;hljs-type&quot;&gt;Literal&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;&quot;ultra-conservative&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;conservative&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;moderate&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;aggressive&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;high risk&quot;&lt;/span&gt;]

&lt;span class=&quot;hljs-keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;State&lt;/span&gt;(&lt;span class=&quot;hljs-title class_ inherited__&quot;&gt;TypedDict&lt;/span&gt;):
    investment_plan: &lt;span class=&quot;hljs-built_in&quot;&gt;str&lt;/span&gt;
    investor_profile: &lt;span class=&quot;hljs-built_in&quot;&gt;str&lt;/span&gt;
    target_grade: grades
    feedback: &lt;span class=&quot;hljs-built_in&quot;&gt;str&lt;/span&gt;
    grade: grades
    n: &lt;span class=&quot;hljs-built_in&quot;&gt;int&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# Initialise the LLM (gpt-4o-mini) and build prompt templates for each persona&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;# … Bobby&amp;nbsp;Axelrod prompt and pipeline&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;# … Gordon&amp;nbsp;Gekko prompt and pipeline with adaptation rules&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;# … Richie&amp;nbsp;Rich evaluator prompt and structured output&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;determine_target_grade&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;state: State&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;Dict&lt;/span&gt;[&lt;span class=&quot;hljs-built_in&quot;&gt;str&lt;/span&gt;, grades]:
    &lt;span class=&quot;hljs-comment&quot;&gt;# Ask the LLM to choose the target risk grade based on the profile&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;investment_plan_generator&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;state: State&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;Dict&lt;/span&gt;[&lt;span class=&quot;hljs-built_in&quot;&gt;str&lt;/span&gt;, &lt;span class=&quot;hljs-built_in&quot;&gt;str&lt;/span&gt;]:
    &lt;span class=&quot;hljs-comment&quot;&gt;# Generate or refine the plan using Bobby or Gordon prompts&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;evaluate_plan&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;state: State&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;Dict&lt;/span&gt;[&lt;span class=&quot;hljs-built_in&quot;&gt;str&lt;/span&gt;, &lt;span class=&quot;hljs-built_in&quot;&gt;object&lt;/span&gt;]:
    &lt;span class=&quot;hljs-comment&quot;&gt;# Evaluate the plan with the Richie Rich evaluator&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;route_investment&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;state: State, iteration_limit: &lt;span class=&quot;hljs-built_in&quot;&gt;int&lt;/span&gt;&lt;/span&gt; = &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;str&lt;/span&gt;:
    &lt;span class=&quot;hljs-comment&quot;&gt;# Decide whether to accept the plan or loop again&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;run_reflection_workflow&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;profile: &lt;span class=&quot;hljs-built_in&quot;&gt;str&lt;/span&gt;&lt;/span&gt;) -&amp;gt; State:
    &lt;span class=&quot;hljs-comment&quot;&gt;# Orchestrate the reflection loop until the target grade is met or the iteration limit is reached&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;10763&quot; data-start=&quot;10437&quot;&gt;The complete implementation can be downloaded as &lt;code data-end=&quot;10519&quot; data-start=&quot;10486&quot;&gt;custom_investment_reflection.py&lt;/code&gt; (file&amp;nbsp;ID &lt;code data-end=&quot;10565&quot; data-start=&quot;10529&quot;&gt; :agentCitation{citationIndex=&#39;0&#39;}&lt;/code&gt;).  This script uses LangChain’s ChatOpenAI to generate and evaluate plans, falls back gracefully if the LLM isn’t available, and demonstrates how to adapt the reflection pattern to custom personas.&lt;/p&gt;&lt;h3 data-end=&quot;10785&quot; data-start=&quot;10765&quot;&gt;Sample Execution&lt;/h3&gt;&lt;p data-end=&quot;11234&quot; data-start=&quot;10787&quot;&gt;As an example, suppose you run &lt;code data-end=&quot;10845&quot; data-start=&quot;10818&quot;&gt;run_reflection_workflow()&lt;/code&gt; from the &lt;code data-end=&quot;10888&quot; data-start=&quot;10855&quot;&gt;custom_investment_reflection.py&lt;/code&gt; module with a 35‑year‑old investor earning $100 k, holding $100 k in assets, aiming to retire by 55 with a generous travel budget, and tolerating high risk.  The workflow determines an &lt;strong data-end=&quot;11088&quot; data-start=&quot;11074&quot;&gt;aggressive&lt;/strong&gt; target grade and iteratively refines the plan.  One possible output (actual results vary slightly with the generative model) is summarised below:&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;12619&quot; data-start=&quot;11236&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre!&quot;&gt;🎯 Final Investment Plan Summary
========================================

📌 Investor Profile:
&lt;span class=&quot;hljs-symbol&quot;&gt;Age:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;35&lt;/span&gt;
&lt;span class=&quot;hljs-symbol&quot;&gt;Salary:&lt;/span&gt; $&lt;span class=&quot;hljs-number&quot;&gt;100&lt;/span&gt;,&lt;span class=&quot;hljs-number&quot;&gt;000&lt;/span&gt;
&lt;span class=&quot;hljs-symbol&quot;&gt;Assets:&lt;/span&gt; $&lt;span class=&quot;hljs-number&quot;&gt;100&lt;/span&gt;,&lt;span class=&quot;hljs-number&quot;&gt;000&lt;/span&gt;
&lt;span class=&quot;hljs-symbol&quot;&gt;Goal:&lt;/span&gt; Retire comfortably &lt;span class=&quot;hljs-keyword&quot;&gt;by&lt;/span&gt; age &lt;span class=&quot;hljs-number&quot;&gt;55&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;with&lt;/span&gt; ample travel budget
Risk tolerance: high

📈 Target Risk Grade: aggressive
📊 Final Assigned Grade: aggressive
🔁 Iterations Taken: &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;

📝 Evaluator Feedback:
----------------------------------
This portfolio &lt;span class=&quot;hljs-built_in&quot;&gt;is&lt;/span&gt; classified &lt;span class=&quot;hljs-keyword&quot;&gt;as&lt;/span&gt; aggressive due &lt;span class=&quot;hljs-keyword&quot;&gt;to&lt;/span&gt; its heavy allocation &lt;span class=&quot;hljs-keyword&quot;&gt;to&lt;/span&gt; equities (&lt;span class=&quot;hljs-number&quot;&gt;75%&lt;/span&gt;) &lt;span class=&quot;hljs-built_in&quot;&gt;and&lt;/span&gt; lower commitment &lt;span class=&quot;hljs-keyword&quot;&gt;to&lt;/span&gt; fixed income.  Ensure the investor &lt;span class=&quot;hljs-built_in&quot;&gt;is&lt;/span&gt; comfortable &lt;span class=&quot;hljs-keyword&quot;&gt;with&lt;/span&gt; higher volatility &lt;span class=&quot;hljs-built_in&quot;&gt;and&lt;/span&gt; periodic drawdowns.

📃 Final Investment Plan:
----------------------------------
Gordon Gekko advises the investor &lt;span class=&quot;hljs-keyword&quot;&gt;to&lt;/span&gt; pursue an assertive course:

### Asset Allocation
- **Equities (&lt;span class=&quot;hljs-number&quot;&gt;75%&lt;/span&gt;)**: Concentrated bets &lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt; blue chips &lt;span class=&quot;hljs-built_in&quot;&gt;and&lt;/span&gt; cyclical industries, supplemented &lt;span class=&quot;hljs-keyword&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;option&lt;/span&gt; strategies.
- **Alternatives (&lt;span class=&quot;hljs-number&quot;&gt;15%&lt;/span&gt;)**: Distressed debt, merger arbitrage &lt;span class=&quot;hljs-built_in&quot;&gt;and&lt;/span&gt; real‑estate investment trusts.
- **Fixed Income (&lt;span class=&quot;hljs-number&quot;&gt;5%&lt;/span&gt;)**: Opportunistic &lt;span class=&quot;hljs-type&quot;&gt;short&lt;/span&gt;‑dated corporate notes.
- **Cash (&lt;span class=&quot;hljs-number&quot;&gt;5%&lt;/span&gt;)**: Dry powder &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; takeover opportunities.

### Rationale
Prioritizing blue chip equities &lt;span class=&quot;hljs-built_in&quot;&gt;and&lt;/span&gt; sector ETFs &lt;span class=&quot;hljs-keyword&quot;&gt;with&lt;/span&gt; active options overlays, complemented &lt;span class=&quot;hljs-keyword&quot;&gt;by&lt;/span&gt; distressed debt &lt;span class=&quot;hljs-built_in&quot;&gt;and&lt;/span&gt; merger arbitrage funds.  Minimal fixed income ensures capital &lt;span class=&quot;hljs-built_in&quot;&gt;is&lt;/span&gt; working hard.

### Risk Management
Use &lt;span class=&quot;hljs-keyword&quot;&gt;stop&lt;/span&gt;‑loss orders &lt;span class=&quot;hljs-built_in&quot;&gt;and&lt;/span&gt; hedges; rebalance monthly &lt;span class=&quot;hljs-keyword&quot;&gt;to&lt;/span&gt; maintain leverage discipline.
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;12916&quot; data-start=&quot;12621&quot;&gt;The first iteration used the Bobby&amp;nbsp;Axelrod persona, which produced a 70 % equity allocation (moderate grade).  The evaluator recommended increasing risk exposure, and the orchestrator rotated to Gordon Gekko, whose 75 % equity allocation met the target.  The system stopped after two iterations.&lt;/p&gt;&lt;h2 data-end=&quot;12971&quot; data-start=&quot;12918&quot;&gt;Pros and Cons of the Reflection Pattern in Finance&lt;/h2&gt;&lt;h3 data-end=&quot;12987&quot; data-start=&quot;12973&quot;&gt;Advantages&lt;/h3&gt;&lt;ul data-end=&quot;14307&quot; data-start=&quot;12989&quot;&gt;
&lt;li data-end=&quot;13259&quot; data-start=&quot;12989&quot;&gt;
&lt;p data-end=&quot;13259&quot; data-start=&quot;12991&quot;&gt;&lt;strong data-end=&quot;13034&quot; data-start=&quot;12991&quot;&gt;Improved quality through self‑critique:&lt;/strong&gt; By iteratively evaluating its own recommendations, the advisor reduces the likelihood of omissions or contradictory allocations.  It mirrors the human practice of drafting and revising (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.philschmid.de/agentic-pattern#:~:text=Reflection%20Pattern&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.philschmid.de/agentic-pattern#:~:text=Reflection%20Pattern&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;philschmid.de&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;13463&quot; data-start=&quot;13260&quot;&gt;
&lt;p data-end=&quot;13463&quot; data-start=&quot;13262&quot;&gt;&lt;strong data-end=&quot;13282&quot; data-start=&quot;13262&quot;&gt;Personalisation:&lt;/strong&gt; Different personas allow the system to explore varied strategies.  Investors can compare aggressive, moderate and conservative approaches without requiring multiple human advisors.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;13728&quot; data-start=&quot;13464&quot;&gt;
&lt;p data-end=&quot;13728&quot; data-start=&quot;13466&quot;&gt;&lt;strong data-end=&quot;13492&quot; data-start=&quot;13466&quot;&gt;Generative creativity:&lt;/strong&gt; When an LLM is available, each persona can craft bespoke investment narratives instead of fixed templates.  This results in plans that read more naturally and incorporate subtle nuances while still adhering to the requested risk grade.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;13931&quot; data-start=&quot;13729&quot;&gt;
&lt;p data-end=&quot;13931&quot; data-start=&quot;13731&quot;&gt;&lt;strong data-end=&quot;13754&quot; data-start=&quot;13731&quot;&gt;Reduced human bias:&lt;/strong&gt; Using fictional characters avoids overreliance on real gurus.  The system still captures different risk appetites but does not misappropriate any celebrity’s actual statements.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;14128&quot; data-start=&quot;13932&quot;&gt;
&lt;p data-end=&quot;14128&quot; data-start=&quot;13934&quot;&gt;&lt;strong data-end=&quot;13952&quot; data-start=&quot;13934&quot;&gt;Extensibility:&lt;/strong&gt; New personas or evaluators can be added without changing the core loop, demonstrating the modularity of the orchestrator–worker pattern (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://dzone.com/articles/ai-agent-architectures-patterns-applications-guide#:~:text=1.%20Orchestrator&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://dzone.com/articles/ai-agent-architectures-patterns-applications-guide#:~:text=1.%20Orchestrator&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;dzone.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;14307&quot; data-start=&quot;14129&quot;&gt;
&lt;p data-end=&quot;14307&quot; data-start=&quot;14131&quot;&gt;&lt;strong data-end=&quot;14160&quot; data-start=&quot;14131&quot;&gt;Autonomy and scalability:&lt;/strong&gt; The loop can be run asynchronously, and evaluation metrics can be refined over time to align with regulatory guidelines or individual preferences.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;h3 data-end=&quot;14324&quot; data-start=&quot;14309&quot;&gt;Limitations&lt;/h3&gt;&lt;ul data-end=&quot;15606&quot; data-start=&quot;14326&quot;&gt;
&lt;li data-end=&quot;14655&quot; data-start=&quot;14326&quot;&gt;
&lt;p data-end=&quot;14655&quot; data-start=&quot;14328&quot;&gt;&lt;strong data-end=&quot;14352&quot; data-start=&quot;14328&quot;&gt;Heuristic evaluator:&lt;/strong&gt; Our evaluation function parses simple percentages and assigns grades.  Real‑world risk analysis is far more complex, involving volatility, correlation and drawdown metrics.  More sophisticated evaluators (e.g., risk‑parity or Monte Carlo simulators) could improve accuracy but also increase complexity.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;14859&quot; data-start=&quot;14656&quot;&gt;
&lt;p data-end=&quot;14859&quot; data-start=&quot;14658&quot;&gt;&lt;strong data-end=&quot;14681&quot; data-start=&quot;14658&quot;&gt;Computational cost:&lt;/strong&gt; Iterative generation and evaluation consume more compute cycles and may require multiple LLM calls.  For high‑frequency use cases, latency and API cost could become prohibitive.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;15098&quot; data-start=&quot;14860&quot;&gt;
&lt;p data-end=&quot;15098&quot; data-start=&quot;14862&quot;&gt;&lt;strong data-end=&quot;14883&quot; data-start=&quot;14862&quot;&gt;Unpredictability:&lt;/strong&gt; Generative models may occasionally omit required allocation details or introduce inconsistent formatting.  Although the evaluator catches gross mismatches, manual review is advisable when using LLM‑generated plans.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;15357&quot; data-start=&quot;15099&quot;&gt;
&lt;p data-end=&quot;15357&quot; data-start=&quot;15101&quot;&gt;&lt;strong data-end=&quot;15128&quot; data-start=&quot;15101&quot;&gt;Potential oscillations:&lt;/strong&gt; Without careful stopping rules, the system might ping‑pong between personas or produce contradictory adjustments.  Clear termination criteria and penalizing repeated mistakes are essential (&lt;span class=&quot;&quot; data-state=&quot;closed&quot;&gt;&lt;span class=&quot;ms-1 inline-flex max-w-full items-center relative top-[-0.094rem] animate-[show_150ms_ease-in]&quot; data-testid=&quot;webpage-citation-pill&quot;&gt;&lt;a alt=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=,loops%20in%20the%20reflection%20process&quot; class=&quot;flex h-4.5 overflow-hidden rounded-xl px-2 text-[9px] font-medium transition-colors duration-150 ease-in-out text-token-text-secondary! bg-[#F4F4F4]! dark:bg-[#303030]!&quot; href=&quot;https://www.analyticsvidhya.com/blog/2024/10/agentic-ai-reflection-pattern/#:~:text=,loops%20in%20the%20reflection%20process&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;relative start-0 bottom-0 flex h-full w-full items-center&quot;&gt;analyticsvidhya.com&lt;/span&gt;&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;15606&quot; data-start=&quot;15358&quot;&gt;
&lt;p data-end=&quot;15606&quot; data-start=&quot;15360&quot;&gt;&lt;strong data-end=&quot;15389&quot; data-start=&quot;15360&quot;&gt;Lack of external context:&lt;/strong&gt; Our fictional personas rely on templates rather than real market data.  Integrating live data feeds and dynamic modelling would make the advice more actionable but also raises regulatory and liability considerations.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-end=&quot;17406&quot; data-start=&quot;17393&quot;&gt;Conclusion&lt;/h2&gt;&lt;p&gt;



































&lt;/p&gt;&lt;p data-end=&quot;18087&quot; data-start=&quot;17408&quot;&gt;The reflection pattern offers a simple yet powerful mechanism for improving AI outputs by letting the model serve as its own critic.  When combined with an orchestrator–worker architecture, it provides a modular and extensible framework for tasks like investment advice, where balancing risk and return requires careful iteration.  By experimenting with fictional personas, we avoid real‑world bias while illustrating how different risk appetites can be encoded in code.  Although our current implementation uses heuristic evaluators and templated advice, it lays the foundation for more sophisticated systems that combine generative AI, financial models and ethical constraints.&lt;/p&gt;</description><link>https://thundaxsoftware.blogspot.com/2025/09/reflection-pattern-for-investment.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOt6jmB2FyPTB8Xb-m6aO1etGbOAhQzU2I-XUOClZEgjEEWJbVq47-r0URqC5IjkSucUxHHGqJB4bf0s2u-tUvDDdj4LOYlST5yYZw5UMIWgNYRdKKmT2X4oZ_mnsaDp7-R9TsxgNc3XiJjJfPFRlihWNnHb9qgQywVtOM41v9FZ5tyJEESFgT1583O2Q/s72-w320-h320-c/fe69c127-4310-47ee-8e47-436d8fd58eb1.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>London, UK</georss:featurename><georss:point>51.5072178 -0.1275862</georss:point><georss:box>23.196983963821154 -35.2838362 79.817451636178845 35.0286638</georss:box></item></channel></rss>