Building Cubic – Part 1: Motivation and Early Prototypes

Every once in a while, I have dropped updates on my account on my socials, that I am working on an app called Cubic, without adding much context. In this post, I want to share a little more about what it is and the chaotic journey it has been to get to the first beta.

TLDR: Cubic started as a news app trying to marry news feeds with serendipitous discovery, but in the last couple of months it has evolved into more a knowledge management app with a “Discover > Collect > Reflect” loop aimed to grow your knowledge of topics over time. You can try the iOS beta app here

Motivation

The change in management at Twitter led to a lot of my connections leaving that network, some for others like Mastodon and Threads, while others just disappeared completely. The algorithms that drove these sites also prioritized engagement, and even the technical articles that would surface up would be mediocre writeups with click-bait titles. As a result I started looking at other sources for news again. Over the next couple of years my news diet became:

  • Technology news aggregators like Hacker News, Lobste.rs and a few Reddit channels
  • Paid subscriptions to a couple of news services (NYTimes and Bloomberg)
  • A handful of Substack accounts
  • The new social media: Threads, Bluesky and Mastodon (in that order right now)

One thing I missed was the lack of a “mix” – my typical news session would tunnel vision me into that source. I really wished I could see a random article from NYTimes next to a random story from Rest of World for example (one of my favorite sites). Almost all of my sources had RSS feeds, so I started thinking if there was a way to pull all of these in and build a mix myself.

Swipe Mechanic

Around the same time, I found a really cool app: Web Roulette let you add any site that had a random link url (like wikipedia random) and every swipe would bring in a new article from your sources. This was cool, but it didn’t do exactly what I was trying to do. I was looking for a little bit more of a “focused random” where instead of random pages from sites I rarely go to, it would pick random pages from sites that I did care about. I actually fixed this by creating a small aggregator web app that pulled in my RSS feeds and then served a random story from that collection.

But it wasn’t enough to just aggregate and serve a random link. Because my set of feeds was small enough, I would often see duplicate articles served. So now I needed to add a history so that set of links the app looked at would not include articles I had already seen.

A web browser and a random source of urls seemed like a simple enough idea, so in mid-2024 I built a prototype in Flutter that seemed to do the job. I had no intention of shipping this. It served my need and it was fun to build.

First Prototype – Sept 2024

The death of Pocket and adding Read-it-later

I was a big Pocket app user (an app Mozilla bought a while back that let you save links that you’d want to read later) and when Mozilla decided it was going to shut down Pocket, adding a read-it-later function seemed a natural feature for my personal news consumption. But that changed the app’s architecture: now I needed a backend system to store the links which I ended up building on Firebase.

But while the initial version in Flutter worked reasonably well, I had started seeing challenges with the implementation

  1. Flutter gave me an abstracted version of the web browser so some of the hooks I wanted to add there were hard to implement
  2. Adding to native extension points in the OS, like share sheets and widgets, is harder with Flutter.

I was curious to re-learn SwiftUI anyway and over one weekend tried to figure out what it would take to convert the app to native. Turns out, not that hard since all the technical decisions had been made already. Once that migration went through, I left the Flutter app behind and focused on the SwiftUI experience.

The app didn’t have a name (it was called WebSpin in the codebase) but I enjoyed using it enough that I figured I should ship some version of it. I shared the first version of “WebSpin” in Feb of 2026.

Webspin v1 (Feb 2026)

Next: From RSS to Knowledge Base

This post has already gone too long so I’ll pause here. In the next post, I’ll detail how this app went from a glorified RSS app to the “Knowledge Management” app that I am really excited about. If you want to try it out, the public beta can be found here. You can also follow me here, or on Threads, BlueSky, Mastodon or Twitter/X to follow the journey.

Building Agentic Systems

For the last 2 years I have built experiences that had features that used AI agents (mostly using LangGraph), but I have learned more in the last 2 months embedded in the team migrating a digital support assistant from the pre-llm-AI world to a new agents-first architecture. And while the goal is to be completely agentic system someday, building a hybrid system with some systems leveraging agents while others don’t has been an interesting challenge.

Choosing an agentic architecture

There is a good post on LangChain’s blog on architectures for multiple agents that explains the details but generally the choice comes down to

  1. A centralized “main” agent coordinating subagents (Fat Main Agent)
  2. A thin main agent essentially acting as a router to domain specific agents (Fat Subagents)

A big part of the decision comes down to how much of the experience do you manage and how much are black boxes you transition to. Fat subagents works if different teams manage different agents and agent-to-agent transitions are infrequent. In this model agent-to-agent transfer also risks context loss as subagents may only see part of the conversation. But, as with microservices, Fat Subagents solve an organizational challenge, not an experiential one. This is also a good option if you are a believer in the vision of A2A experiences, but really, we are ways off from getting there.

In general, I would recommend Fat Main Agent architecture unless you have a strong reason not to do that. Having a central planner and conversation manager leveraging subagents mostly as tools is a good pattern.

A caveat on Fat Agents: In internal debates, there was a concern that loading creating an agent prompt with all the business logic for all behavior would confuse the agent, but that is not how these agents work. Instead agents load skills on-demand which can be pretty efficient, especially if your agents generally only engage in one or two domains in a conversation.

Shallow Agent Hierarchies

One of the challenges in writing software is deciding the granularity of each component that is part of a functional whole. For example, in Object Oriented Programming, you can have many small classes or few giant ones, and both are anti-patterns. How much a component is should do is a matter of good judgement.

In our system, we added way too many subagents each with very narrow set of responsibilities. But as each agent transitioned control to the next one during a conversation turn, we paid the price of those transitions in latency and context loss.

In general avoid architectures with deep agent-t0-agent chains.

Prompt Engineering

While creating a prompt for an agent feels trivial, it can be a rabbit-hole when you see bizarre responses in testing and try to figure out what happened. One of the funniest hallucinations we saw was the agent suddenly acting like the customer – talking about its kids and their day. An internal bug had basically reset it to its default behavior, that of a sentence completion agent and it was helpfully extending the user’s incoming message.

Another thing I do a lot of, copy the prompt and the unexpected output to another agent like Claude or ChatGPT and ask it why the agent responded the way it did. Turns out agents are pretty good at hardening prompt files.

Another interesting learning: turns out agents are better behaved when prompts are structured as XML instead of raw text (I hadn’t realized that Anthropic recommends it as best practice). Explicitly marking tools and behavior in labeled nodes keeps the agent better in check

I need to look more into prompt-versioning, something we don’t really do right now as an independent thing. Each iteration of the prompt is considered a full agent change and we redeploy the entire agent when prompts change.

Keep Subagents independent

Keep all your routing behavior in your main agent (regardless of fat or thin). Domain-specific subagents should generally not call each other, but rather communicate to the central agent when they want to declare that they cannot respond usefully to a user query. For example, a technical troubleshooting agent should never invoke a human-customer-support agent – it should just let the main agent know the results of its processes and let the main agent decide, based on policy, if the human-customer-support agent needs to be invoked.

Memory is a non-trivial detail

Be strategic about what goes into long-term memory and what should be in session-level implementation. This also gets complicated like, in our world, the subagents are often built on different platforms and sharing session data is not an out-of-the-box implementation.

Also, a great video on options for memory systems:

Evals and Mockable Tools

As we move towards probabilistic architectures, human QA might catch less and less of your system’s errors. Shipping without agent-level and system-level evals is just asking for trouble. And since so much of your agent behavior is in its leveraging tools available to it, being able to mock those tools is an essential part of the process. Agents are unpredictable enough and trying to reason their behavior when the input is also not predictable is painful.

For conversational agents, evals can also be used to simulate multi-turn conversations, which most QA scripts tend not to do. Our QA scripts are often structured in “if this then that” patterns, however evals simulate real users trying to achieve a goal and the LLM evaluator may run many turns of a conversation (usually configurable) to try to achieve that goal. The conversation threads of those evals often tend to be very insightful.

Observability

Agents will go wrong in a variety of ways in production and having tools to reconstruct what happened is essential. Agents built on frameworks like ADK are usually deployed as FastAPI applications. And while traditional Observability tools for web applications can be used, a whole new set of tools dedicated to agentic systems is emerging. Tools like Opik, BrainTrust or LangSmith or managed platforms like Google’s Agent Studio not only let you view your application’s behavior in production but also close the loop by integrating evals and prompt versioning allowing you to go from any observed abnormal behavior to a fix in a short time.

The challenges of hybrid systems

While a lot has been written on developing agentic systems in green field scenarios, evolving a non-agentic system to agentic one has had a lot of challenges. The crux of it comes down to underestimating the complexity of adapting tools that were meant to be driven by humans to being driven by an agentic interface acting in between the human and the non-agentic subsystem. Consolidating observability across two very different systems has been a particular challenge and reconstructing a user journey across boundaries has been difficult. User experience can also be jarring as you go from a conversational system to a non-conversational one in one session. The goal now is to accelerate the migration of the rest of the system to the new architecture.

Your mileage may wary based on how your specific non-agentic systems operate.

Notes from a Prediction Markets Meetup

Last week I attended the third meetup by Philadelphia Forecasting Meetup Network on Prediction Markets. I have never played in the prediction markets before, and have no intention to anytime soon, but I have been fascinated by the idea ever since I saw them cropping up in the blockchain space when I was still active there.

Prediction markets take 2 ideas I am personally find challenging: making long term predictions, and making decisions based on your theses. I have read a ton of literature on both these domains but have never been the person who revels in the ambiguity of the space.

The event was fascinating- for one thing I have rarely been in a room with people whose entire careers are based on making predictions – traders, professional poker players, startup founders providing data to prediction markets, app makers, etc. I definitely felt a little bit of an outsider there.

The talk was interesting walking through the history of prediction markets, the challenges of calling the bet in favor of one side or another, when data can be ambiguous (like when governments are closed but not officially reported closed by agencies like the OMB refuse to publish that information, or when dates are involved and the official action is recorded days after the action was executed), and the potential future of prediction markets.

I had not realized that early prediction markets, like The Iowa Electronic Markets (IEM) that began in 1988, were academic efforts that wanted to test whether market mechanisms could aggregate dispersed information better than traditional methods like polling or expert opinion. The early markets also limited the size of the bets which made them better signals than today where people can take out big contracts and then manipulate the markets to win big.

The talk ended with conversations around the future of these markets which will probably be more regulated and how that could be a good thing. The example the speaker gave was interesting: in a more recognized market could airlines hedge their fuel risks via bets on when the Strait of Hormuz would open? Interesting to think about.

Things I read this week (Jan 6, 2023)

Engineering:

  • Figma’s database migration from one giant DB to multiple vertically partitioned databases – My knowledge of database-level aspects of applications is just about functional, relying more on managed services or backend teams to provide my application level code a robust api to work with. However, with my latest project at work, I am starting to look deeper into database elements just to be aware of the tradeoffs we might need to make in the future. This was a great read on how the Figma team transitioned their giant db to a number of vertically partitioned smaller ones and instead of splitting each table across many databases, moved groups of tables onto their own databases. 
  • Computer Scientist Explains Zero Knowledge Proofs in 5 Levels of Difficulty (YouTube) – I really like this YouTube series by Wired that explains technical concepts in ascending levels of complexity/detail. ZKPs are a big topic in my community of Web3 devs and this was a great video that almost everyone can take some learnings away from.
  • Database Fundamentals – A great “from the ground up” read on database technology and concepts. I specially enjoyed the part on various algorithms the database storage engines use.

Design

  • The Genius Design of Dutch Money (YouTube) – It’s a bummer that these are no longer in circulation with Netherlands moving to the Euro, but the focus on clarity and fun make these some of the most interestingly designed currency notes

Fun

  • Children of Time by Adrian Tchaikovsky (Book) – Not surprised that this has won numerous awards and is often talked about as one of the best Science Fiction books of all time. Children of Time explores what happens when a terraforming project goes wrong and a virus designed to speed up simian evolution accidentally ends up evolving spiders instead. I really liked the exploration of civilized spider societies and how their technology would be based on very different primitives than humans’.